HTML第1章 HTML框架第2章 基础文字第3章 表格Table第4章 列表第5章 表单Form5.1 表单属性5.2 输入型 input5.3 标签型 label5.4 下拉表单 select5.5 文本域 textarea第6章 语义化标签第7章 多媒体标签7.1 音频 audio7.2 视频 vedio第8章 框架标签 iframeCSS第1章 CSS基础知识1.1 CSS结构与类型1.2 CSS书写顺序1.3 CSS常用工具1.3.1 emmet语法1.3.2 自动格式化代码1.3.3 兼容性检查1.4 CSS初始化1.5 网站标准1.5.1 文件结构1.5.2 开发技巧1.5.3 头部 head1.5.4 常用模块命名1.5.5 LOGO SEO优化1.5.6 Tab栏切换1.5.7 注册界面第2章 基础属性2.1 字体属性2.2 文本属性2.3 透明度属性2.4 背景属性2.5 边框属性2.5.1 默认边框 border2.5.2 圆角边框 border-radius2.5.3 边框图片 border-image2.6 边距属性2.6.1 内边距:padding2.6.2 外边距:margin2.7 列表属性2.8 阴影属性第3章 高级属性3.1 盒子模型 box-sizing3.2 图片滤镜 filter3.3 计算函数 calc()3.4 过渡效果 transition3.5 2D转换 transform3.5 3D转换 transform3.6 轮播图 swiper第4章 动画效果第5章 选择器5.1 选择器特性5.2 基础选择器5.3 复合选择器5.4 属性选择器5.5 结构伪类选择器5.6 伪元素选择器第6章 显示模式6.1 块级元素6.2 行内元素6.3 行内块元素6.4 元素转换第7章 布局模式7.1 普通布局7.2 浮动布局7.2.1 浮动布局7.2.2 清除浮动7.3 定位布局7.3.1 定位属性7.3.1.1 边偏移7.3.1.2 叠放次序 z-index7.3.2 静态定位:static7.3.3 相对定位:relative7.3.4 绝对定位:absolute7.3.5 固定定位:fixed7.3.6 粘性定位:sticky7.4 隐藏布局7.4.1 显示隐藏:display7.4.2 显示隐藏:visibility7.4.3 溢出显示隐藏:overflow第8章 常用技巧8.1 精灵图 sprites8.2 字体图标 iconfont8.3 CSS三角8.4 用户界面8.5 垂直居中 8.6 溢出文字第9章 移动端设计9.1 移动端基础知识9.1.1 技术选型9.1.2 CSS初始化9.1.3 视口Viewport9.1.4 二倍图9.1.5 特殊属性9.1.6 图片格式9.2 流式布局9.3 flex布局9.3.1 flex特点9.3.2 flex父元素9.3.3 flex子元素9.4 rem布局9.4.1 rem单位9.4.2 媒体查询9.4.3 less语言9.4.4 适配方案9.4.5 文件结构9.5 响应式布局9.5.1 屏幕尺寸9.5.2 Bootstrap框架9.5.2.1 容器9.5.2.2 栅格系统 Grid9.6 vw/vh布局JavaScript第1章 JavaScript介绍1.1 计算机编程基础1.2 初识JavaScript1.3 面向对象编程1.4 JS历史版本第2章 JavaScript基础2.1 JS变量2.1.1 var 关键字2.1.2 let 关键字2.1.3 const 关键字2.1.4 解构赋值2.1.5 globalThis2.2 数据类型2.2.1 简单数据类型2.2.1.1 Number:数字型2.2.1.2 Boolean:布尔值2.2.1.3 String:字符串2.2.1.4 Undefined:未赋值2.2.1.5 Null:空值2.2.2 简单数据类型转换转为字符串转为数字型转为布尔型2.2.3 复杂数据类型2.3 运算符2.3.1 算术运算符2.3.2 递增运算符2.3.3 递减运算符2.3.4 比较运算符2.3.5 逻辑运算符2.3.6 赋值运算符2.3.7 运算符优先级2.3.7 扩展运算符 Spread2.4 流程控制2.4.1 顺序结构2.4.2 分支结构2.4.2.1 if语句2.4.2.2 三元表达式2.4.2.3 switch语句2.4.3 循环结构2.4.3.1 for循环2.4.3.2 while循环2.4.3.3 do while循环2.4.3.4 continue关键字2.4.3.5 break关键字2.4.4 迭代器2.4.5 生成器2.5 数组 Array2.5.1 创建数组2.5.2 检测数组2.5.3 数组长度2.5.4 新增元素2.5.5 删除元素2.5.6 修改元素2.5.7 数组排序2.5.8 数组索引2.5.9 数组截取2.5.10 转字符串2.5.11 数组拼接2.5.12 数组遍历2.5.13 数组筛选2.5.14 数组去重2.5.14 数组降维2.6 字符串 String2.6.1 字符串索引2.6.2 字符串拼接2.6.3 截取字符串2.6.4 替换字符串2.6.5 字符串转数组2.6.6 大小写转换2.6.7 去除空白字符2.6.8 模板字符串2.6.9 匹配字符串2.7 函数 Function2.7.1 声明函数2.7.2 函数参数2.7.2.1 形参与实参2.7.2.2 arguments对象2.7.2.3 函数参数默认值2.7.2.4 rest参数2.7.3 函数返回结果2.7.4 函数的调用2.7.5 改变this指向2.7.6 严格模式2.7.7 高阶函数2.7.8 闭包 Closure2.7.9 递归函数2.7.10 深浅拷贝2.7.10.1 浅拷贝2.7.10.2 深拷贝2.7.11 箭头函数2.8 作用域2.9 预解析2.10 对象 Obejct2.10.1 创建对象2.10.1.1 字面量法2.10.1.2 new关键字2.10.1.3 构造函数2.10.2 调用对象2.10.3 遍历对象2.10.4 对象属性2.10.5 对象方法2.10.6 可选链操作符2.10.7 内置对象2.10.7.1 Math对象2.10.7.2 Date对象2.10.7.3 扩展内置对象2.10.8 原型 Proto2.10.8.1 原型对象:prototype2.10.8.2 对象原型: __proto__2.10.8.3 构造函数 Constructor2.10.8.4 原型链2.10.8.5 this指向2.11 类 Class2.11.1 创建类2.11.2 类的方法2.11.3 静态属性2.11.4 私有属性2.11.5 类的继承2.11.5.1 ES6之后继承2.11.5.2 ES6之前继承2.11.6 get和set2.11.7 this指向2.12 正则表达式2.12.1 创建正则表达式2.12.2 测试正则表达式2.12.3 检索正则表达式2.12.4 元字符2.12.4.1 边界符2.12.4.2 字符类2.12.4.3 量词符2.12.4.4 或者符2.12.4.5 括号类2.12.4.6 预定义类2.12.4.7 常用表达式2.12.5 正则表达式参数2.12.6 正则表达式替换2.12.7 正则表达式匹配2.12.8 命名捕获组2.12.9 反向断言2.12.10 dotAll模式2.13 唯一值 Symbol2.14 集合 Set2.15 高级对象 Map2.16 模块化 Module2.16.1 模块化定义2.16.2 模块化语法2.16.2.1 暴露模块 export2.16.2.2 导入模块 import2.16.2.3 整体导入模块2.16.2.4 动态导入模块2.16.3 Babel模块化转换2.16.4 引入npm包2.17 Promise2.17.1 Promise的基本使用2.17.1.1 Promise简介2.17.1.2 Promise优势2.17.1.3 Promise基本案例2.17.1.4 Promise封装功能2.17.1.5 util.promisify方法2.17.2 Promise API2.17.2.1 Promise构造函数2.17.2.2 Promise.prototype.then2.17.2.3 Promise.prototype.catch2.17.2.4 Promise.resolve2.17.2.5 Promise.reject2.17.2.6 Promise.all2.17.2.8 Promise.allSettled2.17.2.7 Promise.race2.17.3 Promise的关键问题2.18 async与await2.18.1 async函数2.18.2 await表达式2.18.3 async与await结合第3章 Web API3.0 常用方法集锦3.1 API基本概念3.1.1 API简介3.1.2 API重要概念回调函数this指向JS执行机制立即执行函数3.2 DOM3.2.1 DOM简介3.2.2 获取元素3.2.3 事件3.2.3.1 事件介绍事件三要素事件执行步骤DOM事件流:捕获与冒泡3.2.3.2 事件对象基本概念属性和方法3.2.3.3 注册事件3.2.3.4 删除事件3.2.3.5 事件委托3.2.3.6 鼠标事件事件动作事件对象:MouseEvent手动调用事件3.2.3.7 键盘事件事件动作事件对象:KeyboardEvent3.2.3.8 表单事件3.2.4 元素操作3.2.4.1 元素内容3.2.4.2 元素属性修改表单属性设置元素属性获取元素属性移除元素属性3.2.4.3 元素样式3.2.4.4 创建元素3.2.4.5 常用方法排他思想换肤效果表格操作Tab栏切换内容3.2.5 Node操作3.2.5.1 父节点3.2.5.2 子节点3.2.5.3 兄弟节点3.2.5.4 创建节点3.2.5.5 添加节点3.2.5.6 删除节点3.2.5.7 复制节点3.2.5.8 动态创建表格3.3 BOM3.3.1 BOM简介3.3.2 Windows对象3.3.2.1 Windows属性3.3.2.2 Windows方法窗口加载: load窗口大小: resize窗口滚动: scroll定时器: setTimeout本地储存: localStorage3.3.3 location对象3.3.4 navigator对象3.3.5 history对象3.4 网页特效3.4.1 offset偏移量3.4.2 client可视区3.4.3 scroll滚动区3.4.4 动画函数封装3.4.5 轮播图特效3.4.6 返回顶部3.4.7 筋斗云3.4.8 移动端特效3.4.8.1 触摸屏幕3.4.8.2 拖动元素3.4.8.3 移动端轮播图3.4.8.4 视频插件第4章 jQuery4.1 jQuery基本概念4.1.1 jQuery简介4.1.2 入口函数4.1.3 jQuery对象4.1.4 jQuery方法4.2 jQuery API4.2.1 jQuery选择器4.2.1.1 基础选择器4.2.1.2 筛选选择器4.2.1.3 筛选方法4.2.2 jQuery样式操作4.2.2.1 CSS方法4.2.2.2 类样式方法4.2.3 jQuery动态效果4.2.3.1 显示隐藏4.2.3.2 滑动4.2.3.3 淡入淡出4.2.3.4 效果函数参数4.2.3.4 动画停止排队4.2.3.5 自定义动画4.2.4 jQuery属性操作4.2.5 jQuery文本属性4.2.6 jQuery元素操作4.2.6.1 遍历元素4.2.6.2 创建元素4.2.6.3 添加元素4.2.7 jQuery大小操作4.2.8 jQuery位置操作4.3 jQuery事件4.3.1 单事件注册4.3.2 事件处理: on()4.3.3 单次触发: one()4.3.4 事件解绑: off()4.3.5 自动触发: trigger()4.3.6 事件对象: event4.3.7 对象拷贝: extend4.4 jQuery插件Server第1章 Ajax1.1 Ajax基础知识1.1.1 URL1.1.2 客户端与服务器1.1.3 Ajax简介1.1.4 数据接口1.2 HTTP协议1.2.1 HTTP协议简介1.2.2 HTTP请求1.2.3 HTTP响应1.2.4 HTTP请求方法1.2.5 HTTP响应状态代码1.3 XMLHttpRequest1.3.1 GET请求1.3.1.1 一般步骤1.3.1.2 携带参数1.3.2 POST请求1.3.3 封装Ajax1.3.4 新版XHR1.4 数据交换格式1.4.1 XML1.4.2 JSON1.5 jQuery中的Ajax1.5.1 Ajax方法1.5.1.1 GET请求1.5.1.2 POST请求1.5.1.3 Ajax请求1.5.1.4 服务器响应机制1.5.1.5 案例:图书管理1.5.1.6 案例:聊天机器人1.5.2 文件上传1.5.3 ajaxPrefilter1.6 Form表单1.6.1 表单属性1.6.2 同步提交1.6.3 Ajax提交数据1.6.4 案例:评论列表1.7 Axios1.8 跨域与JSONP1.8.1 同源策略与跨域1.8.1.1 同源1.8.1.2 跨域1.8.2 JSONP1.8.2.1 JSONP实现原理1.8.2.2 jQuery发起JSONP请求1.8.3 防抖 debounce1.8.4 节流 throttle第2章 Git2.1 Git基本概念2.1.1 控制系统2.1.1.1 本地版本控制系统2.1.2 集中化的版本控制系统2.1.3 分布式版本控制系统2.1.2 Git基础概念2.2 安装并配置Git2.3 Git操作2.3.1 常用命令2.3.1.1 获取仓库2.3.1.2 检查状态2.3.1.3 暂存文件2.3.1.4 取消暂存2.3.1.5 提交更新2.3.1.6 跳过暂存区直接提交2.3.2 修改文件2.3.2.1 修改已提交文件2.3.2.2 暂存已修改文件2.3.2.3 提交已暂存文件2.3.2.4 撤销修改2.3.3 删除文件2.3.4 忽略文件 gitignore2.3.5 查看提交历史 git log2.3.6 回退到指定的版本2.4 Github2.5 Git分支2.5.1 main主分支2.5.2 本地分支2.5.3 远程分支第3章 Node.js3.1 基础知识3.2 内置API3.2.1 FS模块3.2.2 Path模块3.2.3 Http模块3.3 模块化3.3.1 模块的加载机制3.3.2 Node.js中的模块化3.4 npm与包3.4.0 npm常用包3.4.1 npm简介3.4.3 包的分类3.4.3 npm管理3.4.4 开发自己的包3.4.4.1 定义包3.4.4.2 发布包3.4.4.3 删除包3.5 Express3.5.1 Express简介3.5.2 Express基本用法3.5.3 托管静态资源3.5.4 路由Router3.5.5 中间件Middleware3.5.5.1 中间件简介3.5.5.2 中间件作用3.5.5.3 全局与局部中间件3.5.5.4 中间件分类3.5.6 编写接口3.5.6.1 编写路由3.5.6.2 编写服务器3.6 跨域资源共享3.6.1 CORS3.6.1.1 CORS基本使用3.6.1.2 Access-Control-Allow3.6.1.3 请求分类3.6.2 JSONP3.7 MySQL3.7.1 MySQL基本概念3.7.2 MySQL基本用法3.7.2.1 Workbench3.7.2.2 SQL语句3.7.2.3 SQL函数3.7.3 项目中操作MySQL3.8 身份认证3.8.1 Sessio认证机制3.8.1.1 基于服务端渲染的传统模式3.8.1.2 Session认证3.8.2 JWT认证机制3.8.2.1 基于前后端分离的新型模式3.8.2.2 JWT认证

HTML

第1章 HTML框架

  1. 文件类型:<!DOCTYPE html>

  2. 网站语言:<html lang="zh-CN">

  3. 头部:<head>

    1)<META ...>:编码UTF-8、视图自适应、其他、渲染

    2)标题<title>

  4. 主体:<body>


第2章 基础文字

  1. 标题:<h1><h2><h3><h4><h5><h6>

  2. 段落:<p><br />

  3. 文本格式化:

    1)加粗:<strong><b>

    2)倾斜:<em><i>

    3)删除线:<del><s>

    4)下划线:<ins><u>

  4. 盒子元素:

    1)独占一行:<div>

    2)小箱体:<span>

  5. 图像:<img>

    1)路径:src

    2)替换:alt

    3)标题:title

    4)宽高:width、height

    5)边框:border

  6. 超链接:<a>

    1)打开方式:target

    • 当前窗口(默认):_self
    • 新窗口:_blank

    2)提示文字:title

    3)锚点:

    • 起点:<a href:"#...">
    • 终点:<h3 id="...">
  7. 特殊字符

    1)空格:&nbsp;

    2)左尖头<:&lt;

    3)右尖头>:&gt;

    4)注释:<!-- -->/*


第3章 表格Table

  1. 结构:

    1)表头:<thead>

    2)主体:<tbody>

  2. 元素:

    1)行:<tr>

    2)标题单元格:<th>

    3)单元格:<td>

  3. 属性:

    1)对齐:align

    2)边框:border

    3)文字距单元格距离:cellpadding

    4)单元格之间的距离:cellspacing

    5)宽高:width、height

  4. 合并单元格:

    1)横向合并列:colspan,例:<td colspan="2"></td>

    2)纵向合并行:rowspan,例:<td rowspan="2"></td>


第4章 列表

  1. 无序列表<ul>:项目<li>

  2. 有序列表<ol>:项目<li>

  3. 自定义列表<dl>

    1)项目1:<dt>:一个<dt>对应多个<dd>

    2)项目2:<dd>

     


第5章 表单Form

5.1 表单属性

  1. 动作:action,例:"XXX.php"

  2. 方法:method,例:"POST""GET"

  3. 名称:name

  4. 必填:required

  5. 提示:placeholder,提示文本,若输入文字则自动消失

  6. 自动聚焦:autofocus,页面加载完后光标自动聚焦到指定表单

  7. 自动填写:autocomplate,可填:off/on(默认),必须有name属性,且曾经成功提交过

5.2 输入型 input

  1. 属性

    1)名称:name

    2)值:value

  2. H5之前的类型:type

    1)文字:text,最大长度:maxlength

    2)密码:password

    3)单选:radio

    4)多选:checkbox,选中状态:checked

    5)提交:submit

    6)重置:reset

    7)文件:file,多选文件:multiple

    8)按钮:button

  3. H5之后新增类型:type

    1)邮箱:email:以下类型可添加提交按钮:type="submit" value="提交",可以对输入的值进行验证

    2)网址:url

    3)日期:date

    4)时间:time

    5)数量:number

    6)手机:tel

    7)搜索:search

    8)颜色:color

5.3 标签型 label

  1. 作用:绑定一个表单元素,点击文字即可跳转到表单元素上

  2. 属性:

5.4 下拉表单 select

  1. 选项:<option>

  2. 属性:选中状态:selected="selected"

5.5 文本域 textarea

  1. 属性:列:cols,行:rows

  2. 预留文字:写在<textarea>....</textarea>之间


第6章 语义化标签

兼容性较差,只能在IE9+的浏览器使用,IE9中需要将这些元素转为块级元素(display: block)

  1. 头部标签:<header>

  2. 导航标签:<nav>

  3. 内容标签:<article>

  4. 定义文档某个区域:<section>

  5. 侧边栏标签:<aside>

  6. 尾部标签:<footer>


第7章 多媒体标签

7.1 音频 audio

  1. 格式:MP3(主流)、Wav、Ogg

  2. 考虑兼容性:type,可填:"audio/mpeg""audio/ogg"

  3. 自动播放:autoplay,谷歌禁用了此项功能

  4. 播放组件:controls

7.2 视频 vedio

  1. 格式:MP4(主流)、WebM、Ogg

  2. 地址:src,填写视频地址url

  3. 自动播放:autoplay

  4. 播放组件:controls,一般不显示控制组件

  5. 宽高:widthheight

  6. 循环播放:loop

  7. 预加载:preload

  8. 预加载:auto

  9. 不加载:none

  10. 静音播放:muted

  11. 等待加载的画面:poster,填写图片地址url

  12. 考虑兼容性:type,可填:"vedio/mp4""vedio/ogg"


第8章 框架标签 iframe

  1. 语法:

  2. 配合超链接标签:

    1)href:用来打开的网页地址

    2)target:用来指定在哪里打开网页,例子中在name="fm"的框架中打开网页


 

CSS

第1章 CSS基础知识

1.1 CSS结构与类型

  1. 结构:头部<head>里写<style>...</style>

  2. 样式表类型:

    1)内部样式表:单独写到style标签内部

    2)行内样式表:直接在标签内写样式属性

    3)外部样式表:

1.2 CSS书写顺序

  1. 布局定位

  2. 自身属性

  3. 文本属性

  4. 其他属性

1.3 CSS常用工具

1.3.1 emmet语法

  1. 标签:

    1)输入标签名,按Tab键即可生成

    2)生成多个相同标签,加上*即可,如:div*3 + Tab

    3)生成多个不同选择器的div:.name1+.name2+...+.namex + Tab

    4)生成父子级关系标签,用>即可,如:ul>li + Tab

    5)生成兄弟级关系标签,用+即可,如:div+p+ Tab

    6)生成带有类名或id名的标签,用 标签名.name或#name + Tab

    7)生成带顺序的标签,用 标签名$.name*n + Tab

    8)生成标签内部写内容,用{}表示:标签名{} + Tab

  2. 样式名缩写:数值 + Tab

    1)w200 --> width:200px

    2)lh26 --> line-height:26px

    3)ti2 --> text-indent: 2em

  3. 首字母缩写 + Tab

    1)tac --> text-align: center

    2)tdn --> text-decoration: none

1.3.2 自动格式化代码

1.3.3 兼容性检查

1.4 CSS初始化

  1. CSS reset:消除不同浏览器差异,重设浏览器样式

  2. 所有标签*:内外边距清零

  3. 文字样式em, i:不倾斜

  4. 列表项目li:去掉圆点

  5. 图片img:去除边框、消除图片底侧的空白缝隙

  6. 按钮buttton:鼠标经过时变为小手、设置字体

  7. 超链接a:删除下划线、设置鼠标经过颜色

  8. 输入框input:设置字体

  9. 主体body:CSS3抗锯齿性、背景色、字体("\5B8B\4F53"代表宋体)、字体颜色

  10. 清除浮动:.clearfix:after;.clearfix

1.5 网站标准

1.5.1 文件结构

  1. 样式:css

    1)初始化样式:base.css

    2)公共样式:common.css

    • 首页
    • 列表页
    • 详情页
  2. 脚本:js

  3. 素材:images

  4. 产品:upload

  5. 字体:fonts

1.5.2 开发技巧

  1. 导航栏:

    1)用<li>包含<a>,并给<li>加浮动

    2)如果直接用<a>,搜索引擎容易辨别为有堆砌关键字嫌疑,降低排名

    3)由于导航栏文字不一样多,给<a>左右padding撑开盒子,而不是给宽度

  2. 陈列窗的图片,设定 width=100%,这样不会超出盒子大小

1.5.3 头部 head

  1. 浏览器私有前缀

    1)firefox:-moz-border-radius: 10px

    2)Safari/Chrome:-webkit-border-radius: 10px

    3)Opera:-o-border-radius: 10px

    4)最后添加:border-radius: 10px

  2. SEO优化:TDK

    1)标题:网站名(产品名)-网站介绍30字内

    2)网站说明:SEO专业文案

    3)关键字:6~8个关键词逗号隔开

  3. favicon图标

1.5.4 常用模块命名

  1. 快捷导航栏:shortcut
  2. 购物车:shopcar
  3. 热点词:hotwords
  4. 导航:nav
  5. 导航左侧:dropdown 包含 .dd``.dt
  6. 导航右侧:navitems
  7. 页面底部服务模块:mod_service
  8. 页面底部帮助模块:mod_help
  9. 页面底部版权模块:mod_copyright

1.5.5 LOGO SEO优化

  1. <h1>标签提升权重,里面放置链接可返回首页,背景图设置为logo

  2. 链接里面放文字但不显现:

    1)方法1(淘宝)

    2)方法2(京东)

  3. 给链接一个 title 属性,鼠标放在logo上显示提示文字

1.5.6 Tab栏切换

  1. 用JavaScript实现,但是对HTML结构有严格要求
  2. 分为2个部分:tab_list、tab_content
  3. 可以用box_hd装tab-list,用box_bd装tab-content

1.5.7 注册界面

  1. 不需要做SEO优化,因为保护个人信息隐私

  2. 常用写法:

    1)注册专区:registerarea

    2)注册内容:reg-form

    3)错误/成功/默认:error/success/default


第2章 基础属性

2.1 字体属性

  1. font-style:文字风格

    1)正常:normal

    2)倾斜:italic

  2. font-weight:字体粗细(无单位)

    1)正常:400

    2)加粗:700

  3. font-size:字体大小,标题h1~h6需要单独指定文字大小

  4. font-family:字体类型,可以写多个,用逗号隔开

  5. font:复合简写,默认顺序:文字风格、字体粗细、字体大小/行高、字体类型


2.2 文本属性

  1. color:颜色

    1)预定义文字:deeppink

    2)十六进制:#cc00ff

    3)RGB:rgb(255, 0, 255)

  2. text-align:对齐

    1)left:默认,左对齐

    2)right:右对齐

    3)center:居中对齐(图片居中对齐,要为其父元素添加此代码)

  3. text-decoration:装饰

    1)none:默认,无

    2)underline:下划线

    3)overline:上划线

    4)line-through:删除线

  4. text-indent:缩进,单位:em,表示缩进几个文字大小

  5. line-height:行间距,单位:px,如果写成【字体大小/行高X】的样式,则行高为字体大小的X倍

  6. user-select:用户是否可以选中文字

    1)auto:默认,可选中

    2)none:不可选中


2.3 透明度属性

  1. opacity(0~1):0完全透明,1完全不透明

2.4 背景属性

  1. 背景颜色:background-color

    1)颜色:pink ....

    2)透明:transparent

    3)半透明:rgba(X, X, X, alpha【0~1小数】)

  2. 背景图片:background-img

    1)参数:url(images/logo.png)

    2)注意:页面元素既可以添加背景颜色也可以添加背景图片,只不过背景图片会压住背景颜色

  3. 背景平铺:background-repeat

    1)不平铺:no-repeat

    2)平铺:repeat

    3)沿着X轴平铺:repeat-x

    4)沿着Y轴平铺:repeat-y

  4. 背景固定:background-attachment

    1)背景图片固定:fixed

    2)随着页面其余部分滚动:scroll

  5. 背景位置:background-position:x y

    1)方位名词:topcenterbottomleftcenterright

    • 先写哪个没关系,center right 和 right center是等价的,默认居中对齐

    2)精确单位:

    • 百分数、浮点数字+单位标识符
    • 顺序:第一个肯定是X坐标,第二个肯定是Y坐标(距上顶、左侧的距离)

    3)混合单位:

    • 方位名词+精确单位:第一个肯定是X坐标,第二个肯定是Y坐标
    • 注意:x和y之间没有逗号,是空格!
  6. 背景缩放:background-size:x y

    1)像素单位px:宽、高,只写一个则默认是宽度,高度随着等比例缩放

    2)百分比单位%:相对于父级盒子拉伸,只写一个则默认是宽度,高度随着等比例缩放

    3)cover:等比例拉伸铺满,可能有部分背景图显示不全

    4)contain:宽高等比例拉伸,如果宽或高其中一个铺满盒子就不再拉伸,可能有部分空白

    5)注意:x和y之间没有逗号,是空格!

  7. 复合简写:background,默认顺序:颜色、图片地址、平铺、固定、位置 / 缩放

  8. 背景渐变:background: -webkit-linear-gradient(起始方向,颜色1,眼色2,……)

    1)方位名词:top(默认)、bottomleftright,以及它们的组合使用

    2)注意:必须添加浏览器私有前缀


2.5 边框属性

2.5.1 默认边框 border

边框会向外延伸大小,如盒子大小为200px,10px的边框让盒子整体变为220px

  1. 边框粗细:border-width,单位:px

  2. 边框颜色:border-color

  3. 边框样式:border-style

    1)实线边框:solid

    2)虚线边框:dashed

    3)点线边框:dotted

  4. 边框位置:

    1)上边框:border-top

    2)下边框:border-bottom

    3)左边框:border-left

    4)右边框:border-right

  5. 复合简写:border,没有顺序:粗细、样式、颜色

  6. 表格相邻边框合并:border-collapse

    1)分开:separate(默认)

    2)合并:collapse

  7. 相邻单元格边框间距:border-spacing

    1)仅用于“边框分离 separate”模式

    2)两个数值:水平间隔px,垂直间隔px


2.5.2 圆角边框 border-radius

  1. 边框半径:

    1)单位:px

    2)百分比:50%(半径是宽高的一半,可以做圆形)

  2. 多种写法:例:border-top-left-radius

  3. 复合简写:border-radius,顺序:左上、右上、右下、左下(规则与padding相同)


2.5.3 边框图片 border-image

需要与border、border-width、内部盒子相配合使用,盒子模型设置为 box-sizing:border-box

  1. 作用:盒子大小不一,但边框样式相同,可以自定义边框样式

  2. 图片路径:border-image-source:url(...)

  3. 边框切图:border-image-slice

    边框切图:border-image-slice

    1)原理:把四个角切出去(类似九宫格),中间部分可以铺排、拉抻、环绕

    2)顺序:上、右、下、左(不加单位)

  4. 边框宽度:border-image-width,里面的内容不会被挤压、保持原位

  5. 边框平铺:拉抻的是九宫格上下左右中间部分

    1)平铺:repeat

    2)铺满:round

    3)拉抻:stretch(默认)


2.6 边距属性

不同浏览器有不同的默认设定值,为了统一起见,最好清除默认边距:* {margin: 0;padding: 0;}

2.6.1 内边距:padding

内边距会向外延伸大小,如盒子大小为200px,10px的边距让盒子整体变为220px。

  1. 内边距:padding-XXX,顺时针顺序:上/右/下/左(top/right/bottom/left)

  2. 复合简写:padding

    1)1个值:padding: 5px (上下左右都有5px内边距)

    2)2个值:padding: 5px 10px(上下5px,左右10px)

    3)3个值:padding: 5px 10px 20px(上5px,左右10px,下20px)

    4)4个值:padding: 5px 10px 20px 30px(上5px,左10px,右20px,下30px)

  3. 注意:

    1)如果盒子本身没有指定width/height属性,则padding不会撑开盒子大小

    2)对于子级元素,如果仅是继承了父级元素的width/height属性,padding也不会撑开盒子大小


2.6.2 外边距:margin

外边距不会撑大盒子,但会使盒子周围出现空白。

  1. 外边距:margin-XXX,顺时针顺序:上/右/下/左(top/right/bottom/left)

  2. 块级元素水平居中:

  3. 行内、行内块元素水平居中

  4. 复合简写:margin(与padding规则相同)

    • 特殊应用:auto自动适应
  5. 外边距合并问题

    1)相邻块元素垂直外边距合并:总边距取最大值(上盒子margin-bottom,下盒子margin-top)

    2)嵌套块元素垂直外边距塌陷:对于嵌套父子元素,父元素有上边距,同时子元素也有上边距,此时父元素会塌陷较大的外边距值

    • 为父元素定义上边框:border: 1px solid transparent
    • 为父元素定义上内边框:padding: 1px
    • 为父元素添加:overflow: hidden
    • 注意:浮动、固定、绝对定位的盒子不会有塌陷问题
  6. margin负值应用:浮动盒子一行紧密排列时,如果都有边框,会出现边框合并变粗的问题

    1)写法:margin-left:-1

    2)鼠标移动时显示边框

    • 若盒子无定位,hover里加 pisition:relative,可覆盖盒子
    • 若盒子有定位,hover里加 z-index:1,提高层级

     


2.7 列表属性

  1. 列表项的标记:list-style-type

    1)去掉小圆点:none

    2)实心圆:disc

    3)空心圆:circle

    4)实心方块:suqare

    5)阿拉伯数字:decimal


2.8 阴影属性

  1. 盒子阴影:box-shadow

    1)h-shadow:水平阴影距离,允许负值

    2)v-shadow:垂直阴影距离,允许负值

    3)blur:模糊距离,可选

    4)spread:阴影尺寸,可选

    5)color:阴影颜色,可选

    6)inset:将外部阴影(outset)改为内部阴影,可选

  2. 文字阴影:text-shadow

    1)h-shadow:水平阴影距离,允许负值

    2)v-shadow:垂直阴影距离,允许负值

    3)blur:模糊距离,可选

    4)color:阴影颜色,可选


第3章 高级属性

3.1 盒子模型 box-sizing

  1. content-box(默认):盒子大小 = width+padding+border

  2. border-box:盒子大小 = width(无需再担心边框、内边距撑大盒子)

    • 注意:此时使用line-height=height值不一定能居中对齐了,需要将line-height设置为height减去边框后的大小

3.2 图片滤镜 filter

  1. blur(5px):图片模糊,括号中填写像素大小,越大越模糊

3.3 计算函数 calc()

  1. 宽度计算:width:calc(100%-30),子元素比父元素宽度小30px

3.4 过渡效果 transition

  1. 作用:可以不用Flash或JS的情况下制作元素样式变换的效果,常与:hover配合使用

  2. 书写位置:谁做过渡给谁加,要写在原来的元素上!

  3. 属性:添加多个属性可用逗号分隔,按顺序写

    1)要变换的属性:如width、height,全部变换为all

    2)花费时间 :如 .5s

    3)运动曲线:

    • 逐渐变慢:ease(默认)
    • 匀速:linear
    • 加速:ease-in
    • 减速:ease-out
    • 先加速再减速:ease-in-out

    4)何时开始:延迟触发时间,如 .5s,可省略

3.5 2D转换 transform

  1. 位移:translate(x,y)

    1)单位:px 或 百分比%(相对于自身)

    2)沿轴移动:translateX(n)translateY(n)

    3)水平垂直居中:绝对定位-50%,位移-50%

    4)注意:对行内元素无效,比如<span>

  2. 旋转:rotate(n deg)

    1)单位:deg,正数顺时针,负数逆时针

    2)应用:制作CSS三角形,div旋转45度,只给底部、右侧边框

  3. 中心点:transform-origin:x y

    1)像素:px(x和y之间没有逗号,是空格!)

    2)方位名词:left、right、top、bottom、center

    3)百分比:50% 50%(默认,等价于center center)

    4)应用:制作鼠标移动从底部旋转出现的效果

  4. 缩放:scale(x,y)

    1)2个数字:等于倍数,如scale(2,3)即宽度变成2倍,高度变成3倍

    2)1个数字:等于倍数,如scale(2)即宽高都变成2倍

    3)可以设置缩放中心点,如果写了宽高则以最新数值为参考,且不影响其他盒子位置

  5. 复合简写:transform: translate(x,y) rotatae(n deg) scale(n)

    • 注意:书写顺序会影响效果,有位移的时候必须先写位移

3.5 3D转换 transform

  1. 坐标系:x轴右正左负,y轴下正上负,z轴外正里负

  2. 透视:perspective

    1)单位:px,数值越小,盒子越大

    2)写到被观察元素的父盒子上面,即眼睛到屏幕的距离,近大远小

  3. 3D移动:translate3d(x,y,z)

    1)等价写法:transform: translateX(n) translateY(n) translateZ(n)

    2)x、y、z不能省略,没有就写0

  4. 3D旋转:rotate3d(x,y,z,deg)

    1)x,y,z用:0/1 代表是否选中,并合成矢量,例:rotate3d(1, 1, 0, 45deg)

    2)等价写法:transform:rotateX(n deg) rotateY(n deg) rotateZ(n deg)

    3)X/Y/旋转:左手准则,大拇指指向正轴,四指弯曲指向正角度旋转方向

    4)Z轴旋转:类似2D旋转效果

  5. 3D呈现:trasnform-style

    1)preserve-3d:让子元素保持3D立体空间环境

    2)flat:默认,子元素不开启3D立体空间环境

  6. 案例:两面反转的盒子

  7. 案例:3D导航

  8. 案例:旋转木马

3.6 轮播图 swiper

  1. 插件工具:swiper,网址:www.swiper.com.cn
  2. 下载文件:swiper.min.js、swiper.min.css
  3. 使用方法:找到案例查看源码,复制HTML、CSS、JS代码,按需修改

第4章 动画效果

  1. 语法:中间可以自定义百分比过程

    1)@keyframes 动画名称 { 0% { 开始状态的效果 } 100% {结束状态的效果}}

    2)@keyframes 动画名称 { from { 开始状态的效果 } to {结束状态的效果}}

  2. 调用:至少写动画名称、动画时间2个属性,同一个元素中多个动画可以一起调用,用逗号隔开即可

  3. 属性:

    1)动画名称(必填):animation-name

    2)动画时间(必填):animation-duration

    3)运动曲线:animation-timing-function

    • 效果:ease/ease-in/ease-out/ease-in-out/linear
    • 步长:steps(n),适合做轮播图式动画

    4)延迟时间:animation-delay: 1s

    5)重复次数:animation-iteration-count: infinite/数字次数

    6)反方向播放:animation-direction: alternate(是)/normal(否)

    7)结束后状态:animation-fill-mode: forwards(停留在结束状态)/backwards(默认恢复初始状态)

  4. 播放状态:animation-play-state: paused/running

  5. 复合简写:动画名称(必填),持续时间(必填),运动曲线,延迟时间,重复次数,反方向播放,结束后状态

  6. 案例:无限无缝滚动效果(竖向)

    1)先用JS的遍历clone方法克隆一份元素,添加到大盒子后面

    2)用CSS的@keyframes定义动画,translateY(-50%)

    3)动作效果animation:move 10s linear infinite

  7. 案例:大数据热点图

  8. 案例:无限奔跑的大熊


第5章 选择器

5.1 选择器特性

  1. 层叠性:相同选择器如有最新属性定义,会覆盖旧定义

  2. 继承性:如果不特殊定义子元素选择器,子元素会继承父元素的选择器样式

  3. 优先级:

    1)若选择器相同,执行层叠性

    2)若选择器不同,根据权重执行

    权重适用情况
    (0,0,0,0)继承、*【父级选择器无论权重多大,继承的权重都为0】
    (0,0,0,1)元素选择器、伪元素选择器
    (0,0,1,0)类选择器、伪类选择器、属性选择器、结构伪类选择器
    (0,1,0,0)ID选择器
    (1,0,0,0)行内样式
    无穷大!important
  4. 权重叠加:可以叠加,但不会有进位

5.2 基础选择器

  1. 标签选择器:对HTML默认标签定义属性

  2. 类选择器(最常用):点.+文字(.name)

    1)调用:class="name"

    2)叠加调用:class="name1 name2 ..."

  3. id选择器:井号#+文字(#name)

    1)调用:id="name"

    2)注意:只能调用一次,别人不能使用

  4. 通配符选择器:星号 *,把所有HTML默认标签都进行修改,覆盖全局

5.3 复合选择器

  1. 后代选择器:针对父子级&兄弟级元素嵌套

    1)ol li:针对有序列表中的子项目

    2)ol li a:针对有序列表中子项目中的<a>

    3).nav li a:针对nav类选择器中子项目中的<a>

    4).nav .bg:针对nav类选择器中的bg伪类,只能在nav的子项目中应用

  2. 子元素选择器:只针对嵌套1个层级的子元素

    1).nav>a:只能更改nav类选择器中第1层子项目的<a>

  3. 并集选择器:选取多个元素合并修改,竖着写并用逗号隔开,最后一个选择器不要加逗号

  4. 链接伪类选择器:

    1)未访问的链接:a:link

    2)已访问的链接:a:visited

    3)鼠标经过的链接:a:hover

    4)鼠标按下的链接:a:active

    5)注意:一般要把<a>的默认样式改成不加下划线的

  5. focus伪类选择器:把获得光标的元素选出来,常与input元素结合使用

5.4 属性选择器

  1. 无需借助类/ID选择器:E[att],选中具有att属性的E元素

  2. 选择属性等于某值的某元素:E[att=val],选中具有att属性且属性值等于val的E元素

  3. 选择属性值开头的元素:E[att^=val],匹配具有att属性且值以val开头的E元素

  4. 选择属性值结尾的元素:E[att$=val],匹配具有att属性且值以val结尾的E元素

  5. 选择属性包含某值的某元素:E[att*=val],匹配具有att属性且值包含val的E元素

5.5 结构伪类选择器

  1. 匹配父元素中的第一个子元素:E:first-child

  2. 匹配父元素中最后一个E元素:E:last-child

  3. 匹配父元素中第n个子元素E:E:nth-child(n)

    1)n=数字:选中第n个

    2)n=odd、even:选中奇数/偶数个(隔行效果)

    3)n=公式(从0开始算)

    • n:选中所有
    • 2n:选中偶数
    • 2n+1:选中奇数
    • 5n:选中5的倍数
    • n+3:选中从第3个开始到最后
    • -n+3:选中前3个

    4)执行的时候首先看 :nth-child(n)中的n,即先把所有父元素中的子元素排序,之后回去看前面的E是否能对上,如果不匹配则语法无效

  4. 指定类型E的第一个:E:first-of-type

  5. 指定类型E的最后一个:E:last-of-type

  6. 指定类型E的第n个:E:nth-of-type(n)

    • 执行的时候首先看E,即选中了哪个子元素,之后再去看后面的:nth-child(n)中的n,判断是E中的第n个元素

5.6 伪元素选择器

  1. 语法:element::before/after{ content:XXX;....}(必须有content属性)

  2. 权重:1,与元素选择器一起写的话权重变为2

  3. 作用:利用CSS创建新标签元素,而不需要HTML标签,简化HTML结构,在文档树中找不到

  4. 注意:有行内元素属性,如果想设置宽高需要转换,或添加浮动、定位

  5. 应用1:伪元素字体图标

  6. 应用2:播放缩略图遮罩(伪元素版)


第6章 显示模式

6.1 块级元素

  1. 包括:<div><h1~h6><p><ul><ol><li>

  2. 特点:

    1)自己独占一行

    2)高度、行高、内外边距都可以控制

    3)宽度默认是容器(父级宽度)的100%

    4)是一个大容器及盒子,里面可以放行内或块级元素

  3. 文字类元素内不可使用块级元素:<p><h1~h6>里面不能放其他块级元素

  4. 特殊应用:单行文字垂直居中

    1)直接在<div>中输入文字会顶格显示,而不会垂直居中

    2)设置:hight、line-height 两者同样数值,即可使文字垂直居中

6.2 行内元素

  1. 包括:<span><a><strong><b><em><i><del><s><ins><u>

  2. 特点:

    1)相邻行内元素在一行上,一行可显示多个

    2)高度、宽度直接设置是无效的

    3)默认宽度就是它本身内容的宽度

    4)行内元素只能容纳文本或其他行内元素

  3. 注意:链接里不能再放链接了,如果非要放需要将<a>转为块级元素

6.3 行内块元素

  1. 包括:<input /><img /><td>

  2. 特点:

    1)和相邻行内元素在同一行上,之间有空白缝隙,一行可以显示多个

    2)如果想去掉一行元素之间的空白缝隙,可以设置为浮动排列

    3)默认宽度就是它本身内容的宽度

    4)高度、行高、内外边距都可以控制

  3. 应用:侧边栏

  4. 应用:页码模块,点击跳转页面

6.4 元素转换

  1. 块级元素-->行内元素:display: inline

  2. 行内元素-->块级元素:display: block

  3. 行内元素-->行内块元素:display: inline-block


第7章 布局模式

7.1 普通布局

  1. 名称:普通流、标准流、文档流

  2. 标签按默认方式排列

    1)块级元素独占一行,从上向下排列

    2)行内元素按顺序从左到右排列,碰到父级元素边缘自动换行


7.2 浮动布局

将块级元素<div>转为行内块元素无法紧密排列,中间有空隙,此时使用 float 属性可以解决空隙问题。

7.2.1 浮动布局

  1. 属性:float,选项:noneleftright

  2. 特性:

    1)浮动元素会脱离标准流(脱标),不再保留原位置

    2)浮动元素会一行内显示且元素顶对齐,若父元素装不下则会另起一行对齐

    3)浮动元素具有行内块元素的属性

    • 任何元素都可以浮动
    • 行内元素有了浮动,无需再转为行内块元素,可直接设置宽高
  3. 垂直居中:直接在父元素中定义heightline-height相同值,子元素继承后便垂直居中了

  4. 应用:文字围绕浮动元素:利用浮动不会盖住文字的特性,制作左图+右文字的效果,无需再另用盒子装文字

  5. 注意:

    1)先用标准流父元素排列上下位置,之后内部子元素浮动排列左右位置

    2)若一个子元素浮动,其他元素也要浮动,保证子元素同一行显示

    3)浮动盒子只能影响后面的标准流,无法覆盖前面的标准流

    4)浮动只会压住下面标准流的盒子,但不会压住下面标准流盒子里面的文字、图片,因为浮动最初目的是为了做文字环绕效果的

7.2.2 清除浮动

如果不确定内容长度、子元素数量,父元素无法事先定义高度,但会使下方标准流元素错误排列,需要清除浮动的影响,让父元素自动检测高度

  1. 额外标签法(隔墙法):clear:both(主要)、left、right

    1)末尾新增一个块级元素,属性包含clear

    2)新增的元素必须是块元素,不能是行内元素,否则无效

  2. 父级添加overflow属性:overflow:hidden、auto、scroll

    • 缺点:无法显示溢出部分
  3. 父级添加after伪元素:.clearfix:after

    • 父级元素引用:class="box clearfix"
  4. 父级添加双伪元素:.clearfix:before, .clearfix:after


7.3 定位布局

定位 position:某元素自由在盒子内移动、或固定在屏幕的某个位置,并压住其他盒子。

7.3.1 定位属性

7.3.1.1 边偏移
  1. 方位:顶、底、左、右:top、bottom、left、right
  2. 单位:px
  3. 注意:如果left、right冲突时,按left执行;如果top、bottom冲突时,按top执行
7.3.1.2 叠放次序 z-index
  1. 单位:数字,可正可负,默认为auto,数值越大越靠上

  2. 如果属性相同,按照书写顺序,后来者居上

  3. 只有定位的盒子才有z-index属性

7.3.2 静态定位:static

  1. 定义:默认方式,无定位,依然是标准流

7.3.3 相对定位:relative

原位置继续占有,后面盒子依然以标准流方式对待。元素可以直接设置宽高。

  1. 以元素原来的位置作为参照点

  2. 应用:【子绝父相】父元素用相对定位,子元素用绝对定位;可以不写边偏移,并配合float使用

  3. 注意:

    1)行内元素加绝对、相对定位,可以直接设置宽高

    2)跨级元素加绝对、相对定位,如果不给宽高,默认大小是内容大小

7.3.4 绝对定位:absolute

不在占有原先的位置(脱标),后面元素会“上位”,会完全压住下面盒子的所有内容(与浮动不同之处)。元素可以直接设置宽高。

  1. 若没有祖先元素、或祖先元素没有定位,则以浏览器定位为准(定位于父元素无关了)

  2. 若祖先元素有定位(相对、绝对、固定),则以最近一级的有定位的祖先元素为参考位置

  3. 小技巧:水平垂直居中

  4. 注意:为了照顾IE兼容性,需要加上

  5. 绝对定位会压住下面标准流所有的内容(而浮动布局不会)

  6. 注意:

    1)行内元素加绝对、相对定位,可以直接设置宽高

    2)块级元素加绝对、相对定位,如果不给宽高,默认大小是内容大小

7.3.5 固定定位:fixed

不在占有原先的位置(脱标),后面元素会“上位”,会完全压住下面盒子的所有内容(与浮动不同之处)。

  1. 固定于浏览器可视区的位置,滚动时位置不变

  2. 参考位置:浏览器的可视窗口(默认),与父级元素无关

  3. 必须要有宽度,不然显示不出来;其中的子元素也可以使用绝对定位

  4. 紧贴版心右侧

  5. 水平居中

7.3.6 粘性定位:sticky

相对定位+固定定位的混合,如某元素先随着页面滚动,随后到某位置固定住。

  1. 特点:浏览器的可视窗口(绝对定位特点)+占有原先的位置(相对定位特点)

  2. 必须添加 top、bottom、left、right 其中一个才能有效

  3. 注意:兼容性差,IE完全不支持,尽量用JS实现


7.4 隐藏布局

应用:网站广告,点击关闭就不见了,重新刷新页面又会出现

7.4.1 显示隐藏:display

元素隐藏后,不再占有原来的位置。

  1. none:隐藏元素

  2. block:转换为块级元素、或显示元素;与hover等属性配合,可以做出很多效果

  3. 案例:播放缩略图遮罩(隐藏布局版)

7.4.2 显示隐藏:visibility

元素隐藏后,继续占有原来的位置。

  1. hidden:隐藏元素

  2. visible:显示元素

7.4.3 溢出显示隐藏:overflow

  1. hidden:不显示超过对象尺寸的内容,注意:对于有定位的盒子,慎用hidden,因为会隐藏多余部分

  2. visible:不剪切内容也不加滚动条

  3. auto:剪切内容并添加滚动条(默认)

  4. scroll:无论是否溢出,总显示滚动条


第8章 常用技巧

8.1 精灵图 sprites

  1. 对于网页上的小图片,频繁请求服务器会造成压力,把所有小图拼到一张大图上,利用背景定位原理进行切割,称为精灵图

  2. 位移:利用PS中的x/y轴坐标,注意变为负号,网页端的原点在左上角,水平向右为X轴,垂直向下为Y轴


8.2 字体图标 iconfont

展示的是图标,本质是字体,可以自由变换颜色和大小

  1. 下载站:

    1)icomoon字体库:icomoon.io

    2)iconfont字体库:iconfont.cn

    3)追加:上传之前下载包中的selection.json文件,添加图标后重新下载

  2. 格式:

    1)ttf:Windows、Mac最常见字体

    2)woff:较新的主流字体,不太兼容旧的浏览器

    3)eot:IE专用字体

    4)svg:SVG字体渲染的格式

  3. 使用方法1:

    1)找到style.css中默认代码块,复制粘贴即可

    2)注意路径问题:相对路径要用 ../XXX

    3)span 的样式中指定 font-family:icomoon

    4)在下载站找到对应的方块图标□,或用VS插件找到ttf中对应的符号,复制到

  4. 使用方法2:

    1)引入css文件:

    2)标签调用类名:


8.3 CSS三角

  1. 原理:给没有width的元素加上四个有粗度的边框,将其余三个边框变为透明色

  2. 如果想在元素上方加三角,可以用子绝父相定位,top值设为负数

  3. 应用:价格标签梯形(长方形+直角三角形叠加):上/下边框大,左/右边框小,保证有2条挨着的边为0px,绝对定位


8.4 用户界面

  1. 鼠标样式:cursor

    1)default:小白

    2)pointer:小手

    3)move:移动

    4)text:文本

    5)not-allowed:禁止

  2. 表单轮廓:outline

    1)none:取消蓝色选中轮廓

  3. 防止拖拽:resize

    1)none:防止拖拽textarea右下角


8.5 垂直居中

  1. vertical-align,属性:baselinetopmiddlebottom

  2. 去除图片的顶端缝隙:vertical-align: middle

  3. 文字和图片垂直居中对齐,只针对行内元素、行内块元素有效

  4. 盒子装入图片后加边框,底部有空白缝隙,因为图片默认和文字是基线对齐

    1)方法1:设置图片对齐:vertical-align: middle | top | bottom

    2)方法2:设置图片属性:display:block

     


8.6 溢出文字

  1. 换行:white-spcae

    1)normal:自动换行

    2)nowrap:强制一行内显示

  2. 单行文本:

    1)强制一行内显示:white-spcae:nowrap

    2)超出部分隐藏:overflow:hidden

    3)用省略号代替超出部分:text-overflow:ellipsis

  3. 多行文本:有兼容性问题,适用于webkit浏览器或移动端

    1)隐藏多余部分:overflow:hidden

    2)弹性伸缩盒子模型显示:display:-webkit-box

    3)限制在块元素显示的文本行数:-webkit-line-clamp:3

    4)伸缩盒子子元素的排列方式:-webkit-box-orient:vertical


第9章 移动端设计

9.1 移动端基础知识

9.1.1 技术选型

  1. 单独制作移动端页面(主流)

    1)流式布局(百分比布局)

    2)flex弹性布局(推荐)

    3)less+rem+媒体查询布局

    4)混合布局

  2. 响应式页面兼容移动端:

    1)媒体查询

    2)bootstrap

9.1.2 CSS初始化

  1. 使用 normalize.css
  2. 官网:necolas.github.io/normalize.css/

9.1.3 视口Viewport

  1. 定义:浏览器显示界面内容的屏幕区域

  2. 分类:

    1)布局视口 layout viewport:解决早期PC端界面在手机显示问题,IOS/安卓默认为980px

    2)视觉视口 visual viewport:是网站的区域,可以缩放操作,但不影响布局视口

    3)理想视口 ideal viewport:手动填写meta视口标签,让布局视口宽度与理想视口宽度一致,乔布斯发明

  3. meta标签

    1)width:宽度,可设置device-width特殊值

    2)initial-scale:初始缩放比

    3)maximum-scale:最大缩放比

    4)minimum-scale:最小缩放比

    5)user-scalable:用户是否可以缩放,yes/no (1/0)

9.1.4 二倍图

  1. 像素概念:

    1)物理像素点:分辨率,屏幕的最小颗粒,是物理真实存在的,厂商出厂时已经设置好

    2)物理像素比:1px能显示的物理像素点的个数

    3)开发时1px不一定等于1个物理像素,PC端基本符合,移动端不符合,iphone8中 1px=2个物理像素

    4)注意:chrome模拟器中的尺寸就是开发尺寸的px,已经转换完毕了

  2. 对于低像素的图片,经过retina级别显示屏的放大,会造成模糊的情况,需要二倍图

  3. 方法:手机需要50*50的图片,准备100*100的图片设置宽高缩小为50*50,背景图另外需要用background-size设置

  4. 工具:cutterman

  5. 二倍精灵图:

    1)先用PS把原来的精灵图等比例缩小一半,测量坐标位置 2)background-size: 精灵图原来的宽度一半 auto;

9.1.5 特殊属性

  1. 盒子模型

  2. 点击效果:点击高亮去除

  3. 输入框<input>:去除iOS默认样式,才能给按钮和输入框自定义样式

  4. 图片<img>+链接<a>:禁用长按页面时的弹出菜单

  5. 字体font-family:苹果默认字体

9.1.6 图片格式

  1. dpg:京东推出的一种压缩格式,缩减至1/2,全平台兼容
  2. webp:谷歌推出的一种压缩格式,缩减至2/3

9.2 流式布局

  1. 父盒子设置

  2. 子盒子设置

  3. 案例


9.3 flex布局

9.3.1 flex特点

  1. 任何元素都可以用,布局极为简单,移动端应用广泛,但PC端支持较差
  2. 行内元素也可以直接调整大小
  3. 父元素设为flex布局后,子元素的float、clear、vertical-align都失效
  4. 伸缩布局=弹性布局=伸缩盒布局=flex布局
  5. 父元素为容器(container),子元素为项目(item)

9.3.2 flex父元素

  1. display: flex:flex布局

  2. flex-direction:主轴方向

    1)row:从左到右(默认)

    2)row-reverse:从右到左

    3)column:从上到下

    4)column-reverse:从下到上

  3. justify-content:主轴上子元素的排列方式

    1)flex-start:从头部开始(默认)

    2)flex-end:从尾部开始

    3)center:在主轴居中对齐

    4)space-around:平分剩余空间

    5)space-between:先分布两边,再平分剩余空间

  4. flex-wrap:子元素是否换行

    1)no-wrap:不换行(默认),如果装不开,会自动缩小宽度

    2)wrap:换行

  5. align-items:侧轴上子元素排列方式(单行,flex-wrap: no-warp 不换行)

    1)stretch:拉伸(默认),但主轴沿行/列排列时子盒子不要给高度/宽度

    2)center:挤在一起居中(垂直居中)

    3)flex-start:从上到下

    4)flex-end:从下岛上

  6. align-content:侧轴上子元素排列方式(多行,flex-wrap: warp 换行)

    1)flex-start:从头部开始(默认)

    2)flex-end:从尾部开始

    3)center:在侧轴居中对齐

    4)space-around:平分剩余空间

    5)space-between:先分布两边,再平分剩余空间

    6)stretch:平分父元素高度

  7. flex-flow:复合简写,即同时设置 flex-directionflex-wrap

9.3.3 flex子元素

  1. flex:定义子项目分配剩余空间,表示占多少份数,默认为0

    1)如果单元素为1表示占领所有剩余空间(所有元素全是1的话表示均分空间)

    2)可以写成百分比%,相对父元素而言

  2. align-self:控制子项在侧轴上的排列方式,允许单个元素与其他元素不同的排列方式,可覆盖align-items属性

    1)auto:继承父元素align-items属性(默认),若没有父元素,等同于stretch

    2)flex-start:从头部开始(默认)

    3)flex-end:从尾部开始

    4)center:在侧轴居中对齐

    5)stretch:平分父元素高度

  3. order:定义项目的排列顺序,数值越小排列越靠前,默认为0

    1)与z-index不同之处:order是排列次序,如1、2盒子左右排列可以改成2、1盒子左右排列


9.4 rem布局

通过修改html里面的文字大小来改变页面中元素的大小,可以整体控制,等比例缩放。

9.4.1 rem单位

  1. rem:全称root em,是相对单位,类似于em,em是父元素字体大小,但rem是根元素html元素字体大小

  2. 例:html设置font-size=12px,非根元素设置width=2rem,换成px为24px

9.4.2 媒体查询

  1. 用途:针对不同的屏幕尺寸设置不同样式,最好的方法是按从小到大的尺寸来设置

  2. 语法:@media 媒体类型 and/not/only (媒体特性){...}

    1)媒体类型:

    • all:所有设备
    • print:用于打印和预览
    • screen:用于PC、平板、手机等

    2)关键字:

    • and:且,将多个媒体特性连接到一起
    • not:排除某个媒体类型,可省略
    • only:指定某特定的媒体类型,可省略

    3)媒体特性:

    • width:宽度
    • min-width:最大宽度
    • max-width:最小宽度
  3. 案例:根据不同窗口尺寸,变更页面背景颜色

  4. 案例:配合rem,根据窗口尺寸调整元素大小

  5. 引入资源:

    1)原理:根据屏幕大小引入不同css文件进行适配

    2)语法:<link rel="stylesheet" media="mediatype and|not|only (media feature)" href="stylesheet.css">

9.4.3 less语言

全称Leaner Style Sheets,是一门CSS扩展语言,引入了变量、Mixin、运算、函数功能。(其他CSS预处理器:Sass、Stylus)

  1. less变量:@变量名: 值;,不能包含特殊字符、不能以数字开头、大小写敏感

  2. less编译:由于html不能直接引入less,需要编译成css文件才行

    1)工具:easy LESS

    2)方法:control+s保存之后自动生成css文件

  3. less嵌套:

    1)直接在父选择器里面写子选择器,不用再单独另起一行

    2)如果有伪类、交集选择器、 伪元素选择器,内层选择器:

    • 内层选择器前没有&号,被解析为父选择器的后代
    • 如果有&号,解析为父元素自身或父元素伪类:&:hover&::before
  4. less运算:数字、颜色、变量都可以参与运算(加减乘除)

    1)运算符的左右两侧必须用一个空格隔开

    2)除法需要用括号括起来,如:(80/50rem)

    3)两个数参与运算 如果只有一个数有单位,则最后的结果就以这个单位为准

    4)两个数参与运算,如果2个数都有单位,而且不一样的单位,最后的结果以第一个单位为准

9.4.4 适配方案

  1. 方案1:rem+less+媒体查询

    1)常见屏幕尺寸:750px(大多数适用)

    2)html里的文字大小:把屏幕划分为15等份(也可以是20、10份),每份为50px,设为字体大小,如果屏幕为320px则设置为21.33px

    3)页面元素 rem :页面元素px /(屏幕宽度/划分份数)= 页面元素px / HTML字体大小

  2. 方案2:flexible.js+rem(主流)

    1)简介:手机淘宝团队出品的简洁高效移动端适配库,无需再做媒体查询适配不同屏幕,可以自动计算处理,默认10等份,即在750px的屏幕下设置html文字大小为75px即可

    2)网址:github.com/amfe/lib-flexible

    3)引入JS:<script src="js/flexible.js"> </script>

    4)工具:cssrem,可以自动将px转为rem,但是他默认的字体大小是16px,需要在设置中修改为750px/10=75px

    5)注意:需要限定屏幕宽度最大为750px

9.4.5 文件结构

  1. common.less

    1)常见尺寸:320、360、375、384、400、414、424、480、540、720、750px

    2)划分份数:15份,@no=15;

    3)默认html字体大小为50px,必须写到最上面:html {font-size: 50px;}

  2. index.less:

    1)引入common文件:@import "common"

    2)body指定宽度width: 份数rem,默认15rem

    3)指定基础字体大小:@baseFont: 50px;

    4)所有涉及大小的属性,先在750px分辨率下测量px大小,再转换为rem形式

9.5 响应式布局

利用媒体查询适配不同屏幕宽度,每个宽度下有一个container,令网页大盒子class="container"。

9.5.1 屏幕尺寸

  1. 超小屏幕(手机):<767px,宽度:100%

  2. 小屏设备(平板):768px-991px,宽度:750px

  3. 中屏设备(显示器):992px-1200px,宽度:970px

  4. 大屏设备(大显示器):>=1201px,宽度:1170px

9.5.2 Bootstrap框架

Bootstrap官网下载,复制css/js/font三个文件夹

9.5.2.1 容器
  1. 作用:无需再写媒体查询了,已经预先定义完成了,直接放进<div class="container"></div>即可

  2. container类:响应式布局,固定宽度(先放大缩小屏幕进行试验,选择一个最常用的尺寸进行编辑,再单独对其他尺寸编辑)

    1)大屏(>=1200px):1170px,类前缀:.col-lg-

    2)中屏(>=992px):970px,类前缀:.col-md-

    3)小屏(>=768px):750px,类前缀:.col-sm-

    4)超小屏(<768px):100%,类前缀:.col-xs-

  3. container-fluid类:流式布局,百分百宽度;适合单独做移动端开发

9.5.2.2 栅格系统 Grid
  1. 定义:布局模式,将页面划分成等宽的列,通过列数定义布局,默认划分成12列

  2. 行:class="row",可以消除容器内边距

  3. 用法:

    1)给盒子加上类前缀,最后加数字,使得所有数字之和为12

    2)如果数字相加之和小于12,则不占满整个屏幕

    3)如果数字相加之和大于12,则多于12的列会另起一行显示

    4)全适配

  4. 列嵌套:

    1)在其中一列里再写一个row,里面再放列

    2)如果不写row直接放子列,则有内边距,无法顶边排列

  5. 列偏移:col-md-offset-偏移量

    1)如果是一个盒子,偏移量=(12-盒子所占份数)/2

    2)如果是多个盒子,确保偏移量+盒子所占份数=12

  6. 列排序

    1)左移:col-md-pull-数值

    2)右移:col-md-push-数值

  7. 响应式工具:针对不用设备展示/隐藏页面内容

    1)隐藏:hidden-xshidden-smhidden-mdhidden-lg

    2)显示:visible-xsvisible-smvisible-mdvisible-lg


9.6 vw/vh布局

vw/vh是一个相对单位,vw是viewport width视口宽度,vh是viewport height视口高度(一般使用vw就够了,无需使用vh)

  1. 尺寸:

    1)1vw = 1/100视口宽度

    2)1vh = 1/100视口高度

  2. 换算

    1)元素尺寸/(屏幕尺寸/100):例:375px屏幕下,元素宽50px,换算:50/(375/100)=13.3333vw

    3)工具:像素大厨

    4)插件:px2vw


 

JavaScript

第1章 JavaScript介绍

1.1 计算机编程基础

  1. 编程语言:

    1)汇编语言和机器语言实质是相同的,都是直接对硬件操作,只不过指令采用了英文缩写的标识符,容易识别和记忆。

    2)高级语言主要是相对于低级语言而言,它并不是特指某一种具体的语言,而是包括了很多编程语言,常用的有C语言、C++、Java、C#、Python、PHP、JavaScript、Go语言、Objective-C、Swift等。

  2. 翻译器:高级语言所编制的程序不能直接被计算机识别,必须经过转换才能被执行,为此我们需要一个翻译器。翻译器可以将我们所编写的源代码转换为机器语言,这也被称为二进制化。记住1和0。

  3. 编程语言和标记语言区别:

    1)编程语言有很强的逻辑和行为能力。在编程语言里, 你会看到很多if else 、for 、while等具有逻辑性和行为能力的指令,这是主动的。

    2)标记语言(html)不用于向计算机发出指令,常用于格式化和链接。标记语言的存在是用来被读取的, 是被动的。

1.2 初识JavaScript

  1. 发明者:Brendan Eich,1995年10天完成。最初叫LiveScript由网景公司所有,后来被Sun收购改名为JavaCript。

  2. JavaScript 是什么:JavaScript 是世界上最流行的语言之一,是一种运行在客户端的脚本语言(Script 是脚本的意思)

    • 脚本语言:不需要编译,运行过程中由 js 解释器(js 引擎)逐行来进行解释并执行
    • 现在也可以基于 Node.js 技术进行服务器端编程
  3. JavaScript 的作用:

    • 表单动态校验(密码强度检测)(JS产生最初的目的)
    • 网页特效
    • 服务端开发(Node.js)
    • 桌面程序(Electron)
    • App(Cordova)
    • 控制硬件-物联网(Ruff)
    • 游戏开发(cocos2d-js)
  4. 语言区别:

    1)解释型语言:JavaScript,解释器是在运行时进行及时解释,并立即执行

    2)编译型语言:Java,编译器在代码执行之前进行编译,生成中间代码文件

  5. 浏览器执行JS流程:

    1)浏览器分成两部分:渲染引擎、JS引擎

    • 渲染引擎:用来解析HTML与CSS,俗称内核,比如 chrome 浏览器的 blink ,老版本的 webkit

    • JS引擎:也称为 JS 解释器。用来读取网页中的JavaScript代码,对其处理后运行:

      • Chrome:V8(性能最好)
      • Firefox:OdinMonkey 奥丁猴
      • Safari:JSCore
      • IE浏览器:Chakra 查克拉

    2)浏览器本身并不会执行JS代码,而是通过内置 JavaScript 引擎(解释器) 来执行 JS 代码

    • V8引擎:负责解析和执行 JavaScript 代码
    • 内置API:由运行环境提供的特殊接口,只能在所属的运行环境中被调用(如DOM、BOM、Canvas、XHR等)
  6. JS 的组成:

    1)ECMAScript:JavaScript语法:由ECMA国际(原欧洲计算机制造商协会)标准化的语言,分为JavaScript(网景)、JScript(微软)

    2)DOM:页面文档对象类型:Document Object Model,标准编程接口,对页面上各种元素进行操作(大小、位置、颜色等)

    3)BOM:浏览器对象类型:Browser Object Model,提供独立于内容的、可与浏览器窗口进行互动的对象结构,如弹出框、跳转、获取分辨率等

  7. JS的书写位置

    1)行内式:

    • 可以将单行或少量 JS 代码写在HTML标签的事件属性中(以 on 开头的属性),如:onclick
    • 注意单双引号的使用:在HTML中我们推荐使用双引号, JS 中我们推荐使用单引号
    • 可读性差, 在html中编写JS大量代码时,不方便阅读;
    • 引号易错,引号多层嵌套匹配时,非常容易弄混;
    • 特殊情况下使用

    2)内嵌式:可以将多行JS代码写到<script>标签中,内嵌 JS 是学习时常用的方式

    3)外部式:

    • 利于HTML页面代码结构化,把大段 JS代码独立到 HTML 页面之外,既美观,也方便文件级别的复用
    • 引用外部 JS文件的 script 标签中间不可以写代码
    • 适合于JS 代码量比较大的情况
  8. JS注释

    1)单行注释:ctrl + /

    2)多行注释:shift + ctrl + a

  9. JS输入输出语句

    • 浏览器弹出警示框:alert(msg)
    • 浏览器控制台打印输出信息:console.log(msg)
    • 浏览器弹出输入框,用户可以输入:prompt(info)

1.3 面向对象编程

  1. 面向过程编程(POP)

    1)定义:Process-Oriented Progtamming,用函数一步步实现步骤,依次调用

    2)优点:性能比OOP高,合适跟硬件联系紧密的东西,如单片机

    3)缺点:没有面向对象易维护、易复用、易扩展

  2. 面向对象编程(OOP)

    1)定义:Object-Oriented Progamming:把事务分解成一个个对象,由对象之间分工与合作

    2)特性:封装性、继承性、多态性

    3)优点:易维护、易复用、易扩展,可以设计出低耦合系统,使系统更加灵活、更易于维护

    4)缺点:性能比POP低

1.4 JS历史版本

  1. ECMA(European Computer Manufacturers Association):欧洲计算机制造商协会

  2. ECMAScript :由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言

  3. ES历史版本

    • ES1:1997年,制定了语言的基本语法
    • ES2:1998年,较小改动
    • ES3:1999年,引入正则、异常处理、格式化输出等。IE 开始支持
    • ES4:2007年,过于激进,未发布
    • ES5:2009年,引入严格模式、JSON,扩展对象、数组、原型、字符串、日期方法
    • ES6:2015年,模块化、面向对象语法、Promise、箭头函数、let、const、数组解构赋值等
    • ES7:2016年,幂运算符、数组扩展、Async/await 关键字
    • ES8:2017年,Async/await、字符串扩展
    • ES9:2018年,对象解构赋值、正则扩展
    • ES10:2019年,扩展对象、数组方法
    • ES11:2020年

第2章 JavaScript基础

2.1 JS变量

2.1.1 var 关键字

  1. 变量的使用:

    1)方法1:声明变量:var age,计算机自动分配内存空间,给变量赋值:age = 18;

    2)方法2:变量初始化,例:var age=18;

    3)方法3:不声明直接赋值使用,age = 18;

    4)多变量赋值:可以直接赋值多个变量,用逗号隔开

  2. 变量命名规范:

    1)由字母、数字、下换线_、美元符号$构成,下划线和美元符号都可以开头

    2)严格区分大小写、不能以数字开头

    3)不能是关键字、保留字,如:var、for、while

    4)驼峰命名法,首字母小写,后面单词首字母大写

  3. 变量命名规范的拓展知识:

    1)标识符:开发人员为变量、属性、函数、参数取的名字,不能是关键字、保留字

    2)关键字:JS本身已经使用了的字,不能再用它们充当变量名、方法名

    3)保留字:是预留的“关键字”,现在虽然还不是关键字,但是未来可能会成为关键字

  4. 交换两个变量的值:使用一个临时变量用来做中间存储

2.1.2 let 关键字

  1. 作用:声明非对象类型

  2. 特点:

    1)不允许重复声明

    2)块级作用域:块级作用域包括:if else、while、for、花括号{}等

    3)不存在变量提升:不允许在声明变量之前调用它,直接报错,但如果是var会返回undefinded

    • 不影响作用域链
  3. 可以同时声明多个变量

  4. 经典案例:for循环中的i

    1)使用var,i会成为全局变量,直接跳到最终遍历结果

    2)使用let,i会成为函数变量,可以跟随遍历动态变化


2.1.3 const 关键字

  1. 作用:声明常量、对象

  2. 特点:

    1)声明必须赋初始值

    2)一般常量使用大写(潜规则),不用也不会报错

    3)常量的值不能修改

    4)块级作用域

    5)对于数组和对象的元素修改, 不算做对常量的修改, 不会报错

2.1.4 解构赋值

  1. 定义:从数组和对象中提取值,对变量进行赋值

  2. 数组的解构

  3. 对象的解构

2.1.5 globalThis

  1. 定义:无论执行环境是什么(浏览器、nodejs等),始终指向全局对象。


2.2 数据类型

JavaScript是一种弱类型(动态语言)。这意味着不用提前声明变量的类型,在程序运行过程中,类型会被自动确定。使用typeof获取变量类型。

2.2.1 简单数据类型

2.2.1.1 Number:数字型
  1. 八进制(0-7):数字前加0,例:010,代表8

  2. 十六进制(0-9、a-f):数字前加0x,例:0x9,代表9;0xa,代表10

  3. 数字型最大值:Number.MAX_VALUE

  4. 数字型最小值:Number.MIN_VALUE

  5. 无穷大Infinity:Number.MAX_VALUE * 2

  6. 无穷小-Infinity:- Number.MAX_VALUE * 2

  7. 非数值:NaN,用isNaN()判断,如果是数字返回false,否则为true

  8. Number.EPSILON:是 JavaScript 表示的最小精度,EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16

  9. 二进制和八进制:ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b0o表示。

  10. Number.isFinite:检测一个数值是否为有限数

  11. Number.isNaN:检测一个数值是否为NaN

  12. Number.parseIntNumber.parseFloat:字符串转整数、小数

  13. Number.isInteger:判断一个数是否为整数

  14. BigInt:大整数,用于进行更大的数值运算。语法:整数后加n

2.2.1.2 Boolean:布尔值
2.2.1.3 String:字符串
  1. 用法:单引号(推荐)、双引号

  2. 引号嵌套:单引号内放双引号,反之亦然

  3. 转义符:

    • 换行:\n
    • 斜杠:\\
    • 单引号:\'
    • 双引号:\"
    • tab缩进:\t
    • 空格:\b
  4. 属性:length:长度,例:str.length

  5. 拼接:只要有字符串和其他类型相拼接,最终结果都为字符串

2.2.1.4 Undefined:未赋值
2.2.1.5 Null:空值
  1. JS有个历史遗留问题,如果var x = null; typeof x 输出的是 Object,而不是 Null
  2. 如果有个变量以后打算存储为对象,暂时没想好放啥,这个时候就给 null

2.2.2 简单数据类型转换

转为字符串
  1. .toString():例:var num=1; num.toString()
  2. String():强制转换,例:var num=1; String(num)
  3. 加号拼接字符串(隐式转换):例:var num=1; num + ''
转为数字型
  1. parseInt(string):字符串转整数

    1)只截取整数部分,不做四舍五入

    2)简单自动提取数字部分,如输入"120px”,输出为120

    3)如果开头不是数字,则无法提取,如"rem120px",输出为NaN

  2. parseFloat(string):字符串转小数

  3. Number():强制转换

  4. 减乘除运算(隐式转换):例:"12" - 0、"123"-"120"

转为布尔型
  1. Boolean()

    1)代表空、否定的值都会被转为false:''、0、NaN、null、undefined

    2)其余值都被转为true


2.2.3 复杂数据类型

  1. 定义:又称引用类型,使用new关键字创建的对象(系统对象、自定义对象),如Object、Array、Date

  2. JS中的7种数据类型(USONB):

    • u:undefined
    • s:string 、symbol
    • o:object
    • n:null、number
    • b:boolean
  3. 堆:一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收,复杂数据类型存放到堆中

  4. 过程:首先在栈里面存放地址,十六进制表示,然后这个地址指向堆里面的数据


2.3 运算符

2.3.1 算术运算符

  1. 包括:加+、减-、乘*、除/、取模(取余数)%、幂**

  2. 注意:

    1)浮点数的运算里面会有问题,尽量避免用小数运算

    2)不能直接用浮点数进行比较是否相等

2.3.2 递增运算符

  1. 前提:必须和变量配合使用

  2. 前置递增运算符:++num,等价于 num = num + 1

  3. 后置递增运算符:num++

    1)单独使用:和前置递增效果相同

    2)配合运算:先返回原值,再自加1

  4. 综合案例:

2.3.3 递减运算符

2.3.4 比较运算符

2.3.5 逻辑运算符

  1. 基础符号:与(&&)、或(||)、非(!

  2. 短路运算:当有多个表达式(值)时,左边的表达式可以确定结果时,就不在继续运算右边的表达式的值

    1)与:a && b,若a为真,返回b;若a为假,返回a

    2)或:a || b,若a为真,返回a;若a为假,返回b

    3)注意:如果左侧被短路,右侧前置/后置递增/减运算就不会进行了

2.3.6 赋值运算符

  1. 直接赋值:=
  2. 加减一个数后再赋值:+=-=
  3. 乘除取模后再赋值:*=/=%=

2.3.7 运算符优先级

2.3.7 扩展运算符 Spread

  1. 形式:三个点(...

  2. 作用:好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包

  3. 应用:

    1)数组的合并

    2)数组的克隆

    3)将伪数组转为真正的数组

    4)展开对象(ES9新特性):let newObj = {...obj1, ...obj2, ...obj3}


2.4 流程控制

2.4.1 顺序结构

常规从上到下执行语句。

2.4.2 分支结构

从上到下执行代码时,根据不同条件执行不同的路径代码,得到不同的结果。

2.4.2.1 if语句
  1. if分支语句:if(条件表达式){执行语句}

  2. if else双分支语句:if(条件表达式){执行语句1} else {执行语句2}

  3. if else if多分支语句:if(条件表达式1){执行语句1} else if(条件表达式2){执行语句2} else {执行语句3}

2.4.2.2 三元表达式
  1. 语法:条件表达式 ?表达式1 :表达式2

2.4.2.3 switch语句
  1. 定义:针对变量设置一系列特定值的选项,若表达式值与case后面的value相匹配,则执行条件语句。

  2. 语法:switch (表达式) {case value1: 执行语句1; break; case value2: 执行语句2; break; ...default: 执行最后的语句; }

  3. 注意:

    1)表达式的值和 case 里面的值相匹配的时候是全等(===),值和数据类型全都相同才可以

    2)如果当前的case里面没有break 则不会退出switch,而是继续执行下一个case


2.4.3 循环结构

2.4.3.1 for循环
  1. 语法:for (初始化变量; 条件表达式; 操作表达式) {循环体}

  2. 执行顺序:

    1)var i=1:初始化执行一次

    2)i <= 100:判断

    3)console.log('你好吗'):打印

    4)i++:自增+1

  3. for案例:

2.4.3.2 while循环
  1. 语法:while (条件表达式) {循环体}

  2. 区别:相比for循环,可以判断更复杂的条件

2.4.3.3 do while循环
  1. 语法:do{循环体} while (条件表达式)

  2. 区别:先执行一次循环体,再判断条件,如果表达式为真则继续执行循环体

2.4.3.4 continue关键字
  1. 作用:立即跳出本次循环,继续下一个循环

2.4.3.5 break关键字
  1. 作用:退出整个循环


2.4.4 迭代器

  1. 定义:遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口(可以理解为对象中的属性),就可以完成遍历操作。

  2. ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费

  3. 原生具备 iterator 接口的数据(可用for of遍历)

    • Array
    • Arguments
    • Set
    • Map
    • String
    • TypedArray
    • NodeList
  4. 工作原理:

    1)创建一个指针对象,指向当前数据结构的起始位置

    2)第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员

    3)接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员

    4)每调用 next 方法返回一个包含 valuedone 属性的对象

  5. 需要自定义遍历数据的时候,要想到迭代器


2.4.5 生成器

  1. 定义:生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同

  2. 常见的异步编程:文件操作(fs)、网络操作(ajaxrequest)、数据库操作(mongodb)等

  3. 特点:

    1)*的位置没有限制

    2)生成器函数返回的结果是迭代器对象,调用迭代器对象的next方法可以得到yield语句后的值

    3)yield相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次next方法,执行一段代码

    4)next方法可以传递实参,作为yield语句的返回值

  4. 参数:

    1)在实例化迭代器时,可以传递参数:let iterator = gen('args')

    2)next方法可以传入实参,作为上一个yield语句的返回结果

  5. 案例1:定时器——1s后控制台输出111、2s后输出222、3s后输出333

    1)普通做法:层级嵌套太多,非常麻烦(回调地狱)

    2)生成器函数

  6. 案例2:模拟获取——用户数据、订单数据、商品数据(逻辑:必须先调用用户数据,才有订单数据,然后才有商品数据)


2.5 数组 Array

数组(Array):就是一组数据的集合,存储在单个变量下的优雅方式

2.5.1 创建数组

  1. new方法创建:var 数组名 = new Array()

    1)new Array(2):表示数组的长度为 2,里面有2个空的数组元素

    2)new Array(2, 3):等价于 [2,3]

  2. 数组字面量创建:var 数组名 = [ ]

  3. 获取数组元素:array[index],如果index超出数组长度,返回undefined

2.5.2 检测数组

  1. instanceof:检测对象 instanceof Array

  2. .isArray:Array.isArray(检测对象)

  3. .includes:includes 方法用来检测数组中是否包含某个元素,返回布尔类型值(对比 indexOf,返回的是索引数值,不存在返回-1)

2.5.3 数组长度

  1. 显示长度:arr.length

  2. 修改长度:arr.length=X,新增的元素未赋值前为undefined

2.5.4 新增元素

  1. 直接赋值:arr[i]=X

  2. arr.push(...):在数组末尾添加一个或多个元素

    1)返回结果:新数组长度

    2)直接修改原数组

  3. arr.unshift(...):在数组前面添加一个或多个元素

    1)返回结果:新数组长度

    2)直接修改原数组

2.5.5 删除元素

  1. arr.pop():删除数组的最后一个元素

    1)返回结果:被删除的元素

    2)直接修改原数组

  2. arr.shift():删除数组的第一个元素

    1)返回结果:被删除的元素

    2)直接修改原数组

2.5.6 修改元素

  1. 直接修改:arr[i]=X

  2. arr.splice(开始位置,删除元素数量,插入元素...)

    1)返回值:由被删除的元素组成的一个数组;只删除了一个元素,返回只包含一个元素的数组;如果没有删除元素,则返回空数组

    2)直接修改原数组

2.5.7 数组排序

  1. arr.reverse():颠倒数组元素顺序

  2. arr.sort():对数组元素排序

    1)直接使用:升序排列,但是遇到位数不同的数字,先看个位数、十位数、...进行排序

    2)升序排列:arr.sort(function(a, b) {return a - b;}

    3)降序排列:arr.sort(function(a, b) {return b - a;}

  3. 冒泡排序

    1)原理:一次比较两个元素,如果他们的顺序错误就把他们交换过来,一直循环比较并交换,直到没有元素需要交换为止

    2)外层循环:次数=arr.length -1

    3)内层循环:次数=arr.length - i - 1

    4)内部交换:借助临时变量,交换元素数值

2.5.8 数组索引

  1. arr.indexOf(...):从前开始查找,返回第一个满足条件的索引号,如果没有该元素,返回-1
  2. arr.lastIndexOf(...):从后开始查找,返回第一个满足条件的索引号,如果没有该元素,返回-1

2.5.9 数组截取

  1. arr.slice(开始位置, 结束位置):返回被截取的新数组

2.5.10 转字符串

  1. 普通方法:遍历数组+字符串拼接

  2. arr.toString():默认用逗号分隔

  3. arr.join(分隔符):自定义分隔符

2.5.11 数组拼接

  1. arr1.concat(arr2,arr3,...):返回一个新数组,不影响原数组,

2.5.12 数组遍历

  1. 普通索引方法:

  2. arr.forEach(function(value[,index][,array]){})

  3. arr.reduce(function(accumulator,currentValue[,index[,array]])[,initialValue])

    1)参数:

    • 累计器:accumulator
    • 当前值:currentValue
    • 当前索引:index
    • 源数组:array

    2)案例:

    遍历数组-reduce

  4. 案例:找出两个数组之间的补集(在currentArr但不在arr中的元素)

2.5.13 数组筛选

  1. arr.filter(function(value[,index][,array]){})

    1)创建一个新数组,元素是通过检查指定数组中符合条件的所有元素,用于筛选数组,返回新数组

    2)如果数组里面装的是一个个对象,可以按对象属性值筛选,返回数组中装的元素依然是符合条件的对象

  2. arr.some(function(value[,index][,array]){})

    1)检测数组中的元素是否满足指定条件,查找数组中是否有满足条件的元素,返回布尔值,如果找到第一个满足条件的元素则终止循环

    2)注意:如果在内部函数中写return,一定要跟true终止迭代,否则一直循环下去

    3)区别:forEach、filter中的函数如果写return,不会终止迭代,而some会

2.5.14 数组去重

  1. 自定义去重函数:

2.5.14 数组降维

  1. array.flat(arg):用于将多维数组转化为低位数组,可选参数arg为“深度”,输入数字选择展开层级,默认1层。

  2. array.flatMap(function(){...}):相当于Map和flat的结合,可以把Map返回的多维数组降维,深度为1层。


2.6 字符串 String

  1. 定义:属于基本包装类型,即JS把简单数据类型包装成为了复杂数据类型,使其具有了属性和方法
  2. 不可变性:里面的值不可变,虽然看上去可以改变内容,但其实是地址变了,内存中新开了一个空间,原数据依然存在,所以不要大量拼接字符串

2.6.1 字符串索引

  1. 索引位

    1)str.indexOf('要查找的字符',[起始的位置]),起始的位置可不填,如果未查找到结果,返回-1

    2)str.lastIndexOf('要查找的字符',[起始的位置]),起始的位置可不填,如果未查找到结果,返回-1

    3)注意:所有字符串都包含空字符'',且位置在最前面

  2. 索引值:

    1)str.charAt(index):返回指定位置的字符

    2)str.charCodeAt(index):返回相应索引号的字符ASCII值,目的是判断用户按下了哪个键(ASCII:American Standard Code for Information Interchange,美国标准信息交换代码)

    3)str[index]:获取指定位置处的字符,H5新增

2.6.2 字符串拼接

  1. str.concat(str2,str3,...)

2.6.3 截取字符串

  1. str.substr(开始位置, 截取长度):如果不写截取长度,默认从开始位置一直截取到最后

  2. str.slice(开始位置, 结束位置)

  3. str.substring(开始位置, 结束位置):基本与slice相同,但不接受负数

2.6.4 替换字符串

  1. str.replace('被替换的字符','替换为的字符' )

    1)只会替换第一个字符

    2)若要全部替换,需配合while+indexOf使用,或用正则表达式

2.6.5 字符串转数组

  1. str.split('字符串中的分隔符')

2.6.6 大小写转换

  1. 转换大写:str.toUpperCase()

  2. 转为小写:str.toLowerCase()

2.6.7 去除空白字符

  1. str.trim():去除两端空白字符,不影响字符串本身,返回一个新字符串

  2. str.trimStart()str.trimEnd():trimStart用于删除字符串左侧的空格,trimEnd用于删除字符串右侧的空格。

2.6.8 模板字符串

  1. 定义:是增强版的字符串,用反引号(`)标识

  2. 特点:

    1)字符串中可以出现换行符

    2)可以使用 ${xxx} 形式输出变量

  3. 注意:当遇到字符串与变量拼接的情况使用模板字符串

2.6.9 匹配字符串

  1. str.matchAll(regObj):用来得到正则表达式批量匹配的结果


2.7 函数 Function

2.7.1 声明函数

  1. 函数关键字(命名函数):function 函数名(形参1,形参2,...) {函数体 return...},函数体换行用分号隔开

  2. 函数表达式(匿名函数):var 变量名 = function(形参1,形参2,...) {函数体 return...},调用时用变量名()

  3. 利用Function()构造函数来定义函数:

    1)语法:var f = new Function('参数1','参数2', ..., '函数体'),注意:里面要用字符串的格式写

    2)所有函数都是Function的实例对象

    3)函数也属于对象:f instanceof Object

    Function构造函数

     


2.7.2 函数参数

2.7.2.1 形参与实参
  1. 形参与实参不匹配:

    1)如果实参的个数多于形参的个数,会取到形参的个数

    2)如果实参的个数小于形参的个数,多余的形参定义为undefined,最终输出的结果是 NaN

2.7.2.2 arguments对象
  1. arguments存储了传递的所有实参

  2. 形式:伪数组 Arguments(x)

    1)可用arguments[i]调用

    2)有length属性

    3)没有pop()push()方法

2.7.2.3 函数参数默认值
  1. 定义:ES6允许给函数参数赋值初始值

  2. 形参初始值:具有默认值的参数,一般位置要靠后(潜规则)

  3. 与解构赋值结合

2.7.2.4 rest参数
  1. 形式:...args

  2. 作用:用于获取函数的实参,用来代替 arguments

  3. 注意:rest 参数必须要放到参数最后

  4. 返回:数组Array


2.7.3 函数返回结果

  1. 终止函数:函数中return后面的语句不会被执行

  2. return只能返回一个值,想返回多个值用数组存储

  3. 如果没有return,函数返回的值是undefined


2.7.4 函数的调用

  1. 普通函数:function fn(){}

    1)直接调用:fn()

    2)call()调用:fn.call()

    3)this指向:window(正常调用的完整写法是:window.fn())

  2. 对象中的方法:var obj = {fun: function(){}}

    1)调用:obj.fun() 2)this指向:obj

  3. 构造函数:function Star(){}

    1)调用:var ldh = new Star()

    2)this指向:实例对象ldh(原型对象中的this也指向ldh)

  4. 绑定事件函数:btn.onclick = function(){}

    1)点击按钮调用

    2)this指向:btn

  5. 定时器函数:setInterval(function(){}, 1000) 1)自动1秒钟调用一次

    2)this指向:window(正常调用的完整写法是:window.setInterval())

  6. 立即执行函数:(function(){})()

    1)自动调用

    2)this指向:window


2.7.5 改变this指向

  1. call():function.call(thisArg,arg1,arg2 ...),thisArg:当前调用函数this的指向对象

    1)用法:调用函数:有函数fun(x,y){...},正常可以用fun()调用,也可以用fun.call()调用

    2)改变函数指向:var o = {...}, fun.call (o, x, y), 此时fun中的this指向了对象o

  2. apply():function.apply(thisArg,[argsArray])

    1)参数:

    • thisArg:当前调用函数this的指向对象
    • argsArray:传递的值,必须包含在【数组】里

    2)应用:数组求最大最小值

  3. bind():function.bind(thisArg,arg1,arg2,...),thisArg:当前调用函数this的指向对象

    1)作用:如果有的函数不需要立即调用,但是又想改变这个函数内部的this指向,此时用bind

    2)返回:由指定的this值和初始化参数改造的原函数拷贝(新函数)

    3)注意:不会调用原来的函数,需要手动调用新函数才会执行

    4)案例1:点击按钮后禁用,3秒钟后恢复正常

    5)案例2:Tab栏增删改内容完善(不需要在外部声明that,直接内部修改this指向即可)


2.7.6 严格模式

  1. 定义:ES5的严格模式(Strict Mode)是采用具有限制性JS变体的一种方式,即在严格的条件下运行JS代码

  2. 兼容性:IE10+支持,旧版本浏览器会忽略

  3. 作用:

    1)消除了JS语法不合理、不安全之处,提高编译器效率

    2)禁用了ES未来版本可能会定义的一些语法,为未来版本JS做好铺垫,某些保留关键字不能用作变量名

  4. 语法:

    1)为整个脚本(script标签)开启严格模式

    2)为某个函数开启严格模式

  5. 特性:

    1)变量名必须先声明再使用

    2)不能随意删除已经声明好的变量

    3)全局作用域中函数中的 this 是 undefined

    4)如果构造函数不加new调用, this 指向的是undefined,如果给 this.属性 赋值则会报错

    5)定时器 this 还是指向 window

    6)严格模式下函数里面的参数不允许有重名


2.7.7 高阶函数

  1. 定义:对其他函数进行操作的函数,接收函数作为参数,或将函数作为返回值输出

  2. 接收函数作为参数:

  3. 将函数作为返回值输出:


2.7.8 闭包 Closure

  1. 定义:指有权访问另一个函数作用域中变量的【函数】(注:本质上是函数)

  2. 浏览器检查:F12-来源(source)-代码打断点刷新逐步运行-作用域(scope),可以看到闭包(fn)

  3. 作用:延伸了变量的作用范围

  4. 案例:

    1)案例1:点击li输出索引号

    2)案例2:定时器中的闭包(外面的for循环是同步任务,里面的定时器是异步任务,会产生冲突,需要立即执行函数包裹进去解决问题)

    3)案例3:打车价格


2.7.9 递归函数

  1. 定义:如果一个函数在内部可以调用其本身,这个函数为递归函数

  2. 注意:递归里面必须加退出条件,但如果是有限循环的话就不用加

  3. 案例:

    1)求阶乘

    2)斐波那契数列

    3)深度嵌套数据查找


2.7.10 深浅拷贝

2.7.10.1 浅拷贝
  1. 定义:只是拷贝一层,更深层次对象级别的只拷贝引用,修改拷贝对象会影响原对象

  2. 方法1:用for循环拷贝对象

  3. 方法2:Object.assign(拷贝对象,原对象)

2.7.10.2 深拷贝
  1. 定义:拷贝多层,每一级别的数据都会拷贝

  2. 方法:利用递归函数进行深度拷贝,if 判断数据类型(注意:判断数据类型时,要先筛出数组,因为array即是Object也是Array)


2.7.11 箭头函数

  1. 定义:使用「箭头」(=>)定义函数

  2. 语法:

  3. 特点:

    1)this是静态的:this始终指向函数声明时所在作用域下的this的值

    2)不能作为构造函数实例化

    3)不能使用 arguments变量:在普通函数中,arguments变量是用来储存实参的

    4)箭头函数的简写

  4. 应用场景:

    1)箭头函数适合 this无关的回调:定时器、数组的方法回调

    2)箭头函数不适合与 this 有关的回调:事件回调、对象的方法

  5. 案例1:事件回调函数中的定时器:setTimeout

    1)普通函数:绑定事件后,回调函数内必须先保存this,否则定时器内的回调函数this指向的是windows

    2)箭头函数:定时器内的回调函数使用箭头函数,this依然指向事件函数中的this

  6. 案例2:数组筛选:arr.filter(function(){...})

    1)普通函数

    2)箭头函数


2.8 作用域

  1. 定义:变量在某个范围内起作用和效果,为了提高程序的可靠性,减少命名冲突

  2. 分类:

    1)全局作用域:整个script标签,或者是一个单独的js文件

    2)局部作用域:在函数内部就是局部作用域

    3)块级作用域(ES6):在函数内部用letconst定义变量

  3. 变量作用域:

    1)全局变量:全局作用域下的变量,在全局下都可以使用;只有浏览器关闭的时候才会销毁,比较占内存资源

    • 如果在函数内部,没有声明直接赋值的变量也属于全局变量
    • 没有声明即无var,直接令x=a,例:foo() {var a = 1; b = 2;},b为全局变量

    2)局部变量:在局部作用域下的变量,在函数内部的变量就是局部变量

    • 函数的形参也可以看做是局部变量
    • 当程序执行完毕就会销毁,比较节约内存资源
  4. 作用域链:

    1)就近原则:内部函数访问外部函数的变量,采取的是链式查找的方式来决定取那个值

    2)例:全局变量num=10,函数内局部变量num=20,内部函数调用num,取的是20


2.9 预解析

  1. 预解析

    1)原理:把js里面所有的 var 和 function 提升到当前作用域的最前面

    2)变量提升:把所有的变量声明提升到当前的作用域最前面,不提升赋值操作

    3)函数提升:把所有的函数声明提升到当前作用域的最前面 ,不调用函数

  2. 代码执行:按书写顺序从上到下执行

  3. 案例:

    1)先调用变量但后赋值,输出结果为undefined

    2)先用变量名调用匿名函数后定义函数,提示报错

    3)先调用命名函数但后定义函数,可以成功运行

  4. 经典案例:

    1)var a = b = c = 9; 仅有a是局部变量,b、c都是直接赋值,为全局变量

    2)想同时赋值多个变量,要用逗号隔开:var a = 9, b = 9, c =9;


2.10 对象 Obejct

对象是一组无序的相关属性和方法的集合,所有事物都是对象,如字符串、数值、数组、函数等。

2.10.1 创建对象

2.10.1.1 字面量法
  1. 传统写法:var 对象名 = {key1:value1,key2:value2,key3:function(){}....}

  2. 简化对象写法:在大括号里面直接写入变量和函数,作为对象的属性和方法

2.10.1.2 new关键字
  1. 语法:var 对象名 = new Object()

  2. 定义属性:对象名.属性名 = 属性

  3. 定义方法:对象名.方法名 = function() {...}

  4. new关键字执行过程

    1)new 构造函数可以在内存中创建了一个空的对象

    2)this 就会指向刚才创建的空对象

    3)执行构造函数里面的代码 给这个空对象添加属性和方法

    5)返回这个对象

2.10.1.3 构造函数
  1. 定义:如果需要重复引用同一个对象进行定义,可以利用函数的方法重复相同的代码,称为构造函数

  2. 目前大多数浏览器的JS是ES5版本,少部分高版本浏览器支持ES6;ES5中的对象不是基于类创建的,而是基于构造函数创建的

  3. 缺点:存在浪费内存的问题,每进行一次实例化,便新开辟一个内存空间

  4. 规则:

    1)构造函数名字首字母要大写

    2)构造函数不需要return就可以返回结果

    3)用构造函数必须使用new

    4)属性和方法前面必须添加this

  5. 语法:function Classname(arg1,arg2,...){this.attr1=arg1 this.attr2=arg2 this.method=function(){...}}

  6. 实例成员:构造函数内部通过this添加的成员,只能通过实例化的对象来访问

  7. 静态成员:在构造函数本身上添加的成员(在外部后添加的),只能通过构造函数来访问,不能通过实例化对象来访问


2.10.2 调用对象

  1. 调用属性:

    1)对象名.属性名:object.attribute

    2)对象名['属性名']:object['attribute']

  2. 调用方法:对象名.方法名():object.method()

2.10.3 遍历对象

  1. 传统方法:for (var k in obj) {obj[k]}

  2. Object.keys():用于获取对象自身所有的属性名

2.10.4 对象属性

  1. 传统方法:obj.属性名=属性值

  2. ES5新方法:Object.defineProperty(obj,prop,descriptor)

    1)descriptor说明:以对象的形式书写

    • value:设置属性值,默认为undefined
    • writable: 布尔值,值是否可以重写,默认为false
    • enumerable: 布尔值,目标属性是否可以被枚举,默认为 false,即Object.keys()是否可以遍历出该属性
    • configurable:布尔值,目标属性是否可以被删除或是否可以再次修改特性,默认为false,如果已经设置过一次descriptor了,不允许在下面再次修改descriptor中的参数

    2)对于obj初始时内部定义的属性,descriptor中后三项默认都是true


2.10.5 对象方法

  1. Object.is:比较两个值是否严格相等,与===行为基本一致(+0 与 NaN)

  2. Object.assign:对象的合并,将源对象的所有可枚举属性,复制到目标对象,如果属性重名则会覆盖掉

  3. __proto__setPrototypeOfsetPrototypeOf:可以直接设置对象的原型

  4. Object.keys():返回一个给定对象的所有可枚举属性键的数组

  5. Object.values():返回一个给定对象的所有可枚举属性值的数组

  6. Object.entries():返回一个给定对象自身可遍历属性[key,value]的数组

  7. Object.getOwnPropertyDescriptors():返回指定对象所有自身属性的描述对象(writable、configurable、enumerable)

  8. Object.fromEntries():ES10新特性,用来创建对象,但参数比较特殊,接收一个二维数组或Map


2.10.6 可选链操作符

  1. 格式为问号+点(?.),用于简化判断深层级对象中的属性和方法。


2.10.7 内置对象

内置对象:JS已经定义好的,直接拿来使用即可,都是首字母大写的。

2.10.7.1 Math对象
  1. 定义:不是构造函数,不用new实例化

  2. 圆周率:Math.PI

  3. 最大值:Math.max()

  4. 最小值:Math.min()

  5. 绝对值:Math.abs(),如果输入字符串自动转为数字

  6. 向下取整:Math.floor(),往小了取值

  7. 向上取整:Math.ceil(),往大了取值

  8. 四舍五入:Math.round(),0.5往大取,1.5变成2,-1.5变成-1

  9. 将数字的小数部分抹掉:Math.trunc()

  10. 判断一个数到底为正数、负数、还是零:Math.sign()

  11. 随机数:Math.random(),取值范围 [0,1)

2.10.7.2 Date对象
  1. 定义:是构造函数,需要new实例化

  2. 语法:var date = Date(参数),如果没有参数,返回系统当前时间

  3. 参数:

    1)数字型:2019,10,01,注意:数字型月份默认+1,即输入10,输出为11月

    2)字符串:'2019-10-1 8:8:8'

  4. 格式化:var date = new Date()

    1)获取当年:date.getFullYear()

    2)获取当月:date.getMonth(),注意:返回的数值需要+1才是当前月份

    3)获取当天日期:date.getDate()

    4)获取星期几:date.getDay(),注意:周日返回的是0,最好用数组自定义一下,然后arr[day]

    5)获取当前小时:date.getHours(),补零:h = h < 10 ? '0' + h : h

    6)获取当前分钟:date.getMinutes(),补零:m = m < 10 ? '0' + m : m

    7)获取当前秒钟:date.getSeconds(),补零:s = s < 10 ? '0' + s : s

  5. 时间戳:当前距离1970年1月1日的总毫秒数

  6. 案例:倒计时

    1)输入的时间减去现在的时间就是剩余的时间,但是不能拿着时分秒相减,比如05分减去25分,结果会是负数的

    2)用时间戳:用户输入时间总的毫秒数减去现在时间的总的毫秒数,得到的就是剩余时间的毫秒数

    3)把剩余时间总的毫秒数转换为天、时、分、秒 (时间戳转换为时分秒)

    • 毫秒转为秒:除1000
    • 计算天数:parseInt(总秒数/ 60/60 /24)
    • 计算小时:parseInt(总秒数/ 60/60 %24)
    • 计算分钟:parseInt(总秒数 /60 %60 )
    • 计算秒数:parseInt(总秒数%60)
2.10.7.3 扩展内置对象
  1. 作用:通过原型对象prototype,对JS内置对象进行扩展自定义的方法,如给Array添加求和的功能

  2. 正确写法:

  3. 错误写法:即使用constructor: Array重新定向也不行,内置对象扩展方法必须用上面的写法


2.10.8 原型 Proto

2.10.8.1 原型对象:prototype
  1. 定义:

    1)每个构造函数都有一个prototype属性,指向另一个【对象】,这个对象的所有属性和方法,都会被构造函数拥有

    2)把不变的方法直接定义在 prototype 对象上,所有对象实例都可以共享这些方法,可以有效解决浪费内存问题

  2. 语法:Object.prototype.method = function() {...}

    1)一般来说,公共属性定义到构造函数里面,公共的方法放到原型对象身上

    2)用原型在外部定义的成员,可以通过实例对象访问

2.10.8.2 对象原型: __proto__
  1. 定义:每个对象都会有一个属性__proto__指向【构造函数】的【原型对象prototype】,之所以对象可以使用【构造函数】的【原型对象prototype】的属性和方法,就是因为对象有__proto__原型存在

  2. 实例化对象的__proto__指向【构造函数】的【原型对象prototype】

  3. 方法的查找规则:

    1)首先先看ldh对象身上是否有sing方法,如果有就执行这个对象上的sing

    2)如果没有sing这个方法,因为有__proto__的存在,就去【构造函数Star】的【原型对象prototype】身上去查找sing这个方法

    3)__proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线

2.10.8.3 构造函数 Constructor
  1. 定义:

    1)【对象原型(__proto__)】和【构造函数】的【原型对象(prototype)】里都有一个constructor属性,指回【构造函数】本身

    2)用于记录该对象引用于哪个构造函数,可以让原型对象prototype重新指向原来的构造函数

  2. 作用:由于通过【原型对象prototype】定义公共的方法,而方法往往有多个,不可能重复书写,此时需要重新定义【原型对象prototype】

    1)单一公共方法的定义

    2)多个公共方法的定义:此处修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数

2.10.8.4 原型链

原型链

  1. 只要是对象就有__proto__原型,指向原型对象【Object.prototype】

  2. 【Object.prototype】原型对象里面的__proto__原型,指向为 null

  3. 成员查找规则(就近原则)

    1)先看 ldh 自身是否有该属性/方法

    2)没有的话查找它的原型 Star.prototype(即 ldh.__proto__ 所指向的)

    3)还没有的话查找原型对象的原型 Object.prototype(即 Star.prototype.__proto__ 所指向的)

    4)再没有的话,返回 Object.prototype.__proto__,即 null

    5)注意:ldh、Star、Object身上可能有相同属性名但不同属性值的情况,此时要就近原则查找

2.10.8.5 this指向
  1. 都指向实例对象 ldh:

    1)构造函数 Star(){...} 中的this

    2)原型对象函数 Star.prototype.sing = function() {...} 中的this


2.11 类 Class

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

2.11.1 创建类

  1. 类必须使用new实例化对象

  2. 构造函数:constructor()

    1)定义:接受传递过来的参数,同时返回实例对象,只要 new 生成实例时就会自动调用这个函数

    2)语法:class Name {constructor(arg) {this.xx = arg ... }}

  3. 注意:

    1)ES6中类没有变量提升,所以必须先定义类,才能通过类实例化对象

    2)类里面的共有的属性和方法一定要加this使用

    3)在类中调用内部定义的函数,不用加括号

  4. 类其实是构造函数的另一种写法而已:

    1)类有原型对象prototype:Star.prototype

    2)类原型对象prototype里面有constructor指向类本身:Star.prototype.constructor

    3)类可以通过原型对象添加方法:Star.prototype.sing = function () {...}

    4)类创建的实例对象有__proto__原型指向类的原型对象:ldh.__proto__ === Star.prototype

2.11.2 类的方法

  1. 语法:直接写到类里面即可,在constructor下面写

  2. 注意:不用写function关键字,直接写函数名,如 sing(song) {...},函数/方法之间不能加逗号分割

2.11.3 静态属性

  1. 定义:属于类的属性和方法,但不属于实例对象的属性和方法

  2. ES5方法:给实例对象添加属性和方法,使用 Obj.prototype,直接在类上添加的属性和方法,属于静态方法

  3. ES6方法:使用static定义静态方法

2.11.4 私有属性

  1. 定义:私有属性是不能被直接访问的属性,在属性名前添加井号#即可。需要在外部先单独声明,如果要访问,需要在类内部定义访问函数。

2.11.5 类的继承

2.11.5.1 ES6之后继承
  1. 就近原则:

    1)继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的

    2)如果子类里面没有,就去查找父类有没有这个方法,如果有就执行父类的这个方法

  2. extends关键字:class Son extends Father {...}

  3. super关键字:用于访问和调用父类上的函数,可以调用父类的构造函数、普通函数

    1)调用构造函数

    2)调用普通函数

  4. 继承的同时扩展自己的方法:

    1)利用super调用父类的构造函数(注意:super 必须在子类this之前调用)

    2)然后直接在子类的构造函数下写自己的函数方法

2.11.5.2 ES6之前继承
  1. 组合继承:构造函数+原型对象,模拟实现继承

  2. function.call(thisArg,arg1,arg2,...):thisArg:当前调用函数this的指向对象

    1)作用:修改函数运行时的this指向

    2)调用函数:有函数fun(x,y){...},正常可以用fun()调用,也可以用fun.call()调用

    3)改变函数指向:var o = {...}, fun.call (o, x, y), 此时fun中的this指向了对象o

  3. 借用父构造函数继承【属性】:在子构造函数中添加 Father.call(this, arg1,arg2,...)

  4. 借用原型对象继承【方法】:子构造函数的原型对象=new 父构造函数,同时用constructor指回子构造函数

2.11.6 get和set

  1. get:获取属性

  2. set:对某属性进行设置

2.11.7 this指向

  1. constructor中的this指向的是创建的实例对象

  2. 类的方法函数中的this指向的是调用它的对象,一般就是实例对象

    • 特殊案例:如果在构造函数中调用内部函数,比如点击按钮触发函数,函数中的this指向的是按钮
  3. 如果想保留constructor中的this指向,最好用其他变量保存一下,防止命名冲突,如:that = this(先在类的外面声明全局变量 var that)


2.12 正则表达式

Regular Expression,用于匹配字符串中字符组合的模式,在JS中正则表达式也是对象。

2.12.1 创建正则表达式

  1. 调用RegExp对象的构造函数:var 变量名 = new RegExp(/表达式/)
  2. 利用字面量创建:var 变量名 = /表达式/
  3. 注意:正则表达式里面不需要加引号,不管是数字型还是字符串型

2.12.2 测试正则表达式

  1. 检测字符串是否符合规则,返回布尔值

  2. 语法:regObj.test(str)

  3. 正则测试工具:http://tool.oschina.net/regex

2.12.3 检索正则表达式

  1. exec()函数:regObj.exec(string),用于检索字符串中的正则表达式的匹配,如果有匹配的值,返回该匹配值,否则返回null

2.12.4 元字符

2.12.4.1 边界符
  1. ^:表示匹配行首的文本

  2. $:表示匹配行尾的文本

  3. 如果^$在一起,表示必须是精确匹配

2.12.4.2 字符类
  1. []:只要包含里面任意一个字符即可

  2. ^[]$:只能是包含其中任意一个字符的单个字符

  3. [-]:表示范围,如[a-z]代表包含任意26个字母之一即可

  4. ^[a-zA-Z0-9_-]$:26个大小写英文字母+0-9数字+下划线_+短横线-,包含任意其中之一的一个

  5. [^]:方括号内部取反符^,只要包含其中任意字符,都返回false

2.12.4.3 量词符
  1. *:可以出现0次或很多次

  2. +:可以出现1次或者很多次

  3. ? :可以出现0次或1次

  4. {n}:重复n次

  5. {n, }:大于等于n次

  6. {n,m}:大于等于n次,并且小于等于m次(注意:n,m之间不要有空格)

  7. var reg = /^[a-zA-Z0-9_-]{6,16}$/:26个大小写英文字母+0-9数字+下划线_+短横线-,包含任意其中之一,6-16个字符之间

     

2.12.4.4 或者符
  1. 或者符:|
2.12.4.5 括号类
  1. 小括号():表示优先级,可与模板语法配合:{{(...)}}小括号内表示一个分组,提取想要的内容

  2. 中括号[]:字符集合,匹配方括号中的任意字符

  3. 大括号{}:量词符,里面表示重复次数

2.12.4.6 预定义类
  1. \d:匹配一个数字字符,等价于[0-9]

  2. \D:匹配一个非数字字符,等价于`[^0-9]``

  3. \w:匹配包括下划线的任何单词字符,等价于[A-Za-z0-9_]

  4. \W:匹配任何非单词字符,等价于[^A-Za-z0-9_]

  5. \s:匹配任何空白字符,包括空格、制表符、换页符等等,等价于[ \f\n\r\t\v]

    1)\f:匹配一个换页符,等价于\x0c\cL

    2)\n:匹配一个换行符,等价于\x0a\cJ

    3)\r:匹配一个回车符,等价于\x0d\cM

    4)\t:匹配一个制表符,等价于\x09\cI

    5)\v:匹配一个垂直制表符,等价于\x0b\cK

  6. \S:匹配任何非空白字符,等价于[^ \f\n\r\t\v]

2.12.4.7 常用表达式
  1. 座机号:

    1)区号(3-4位):/^\d{3,4}-\d{7,8}$/

    2)座机号(7-8位):/^\d{3}-\d{8}|\d{4}-\d{7}$/

  2. 表单验证

    1)手机号:/^1[3|4|5|7|8]\d{9}$/

    2)QQ号:/^[1-9]\d{4,}$/

    3)中文昵称:/^[\u4e00-\u9fa5]{2,8}$/

    4)短信验证码:/^\d{6}$/

    5)密码:/^[a-zA-Z0-9_-]{6,16}$/

2.12.5 正则表达式参数

  1. 语法:/表达式/[switch],switch又称修饰符,表示按照什么样的模式匹配
  2. 全局匹配:g
  3. 忽略大小写:i
  4. 全局匹配+忽略大小写:gi

2.12.6 正则表达式替换

  1. repalce():stringObject.replace(regexp/substr,replacement)

  2. 用法:

  3. 注意:只能替换第一个满足条件的字符串,后面的不会替换,如果要全部替换令switch=g

2.12.7 正则表达式匹配

  1. match():stringObject.match(searchvalue/regexp)

  2. 返回:指定的值,而不是字符串的位置

  3. 注意:如果使用正则匹配,一定要配合g进行全局匹配

  4. 案例:与replace搭配,动态匹配值

2.12.8 命名捕获组

ES9允许命名捕获组使用符号?<name>,这样获取捕获结果可读性更强,无需通过改变index来获取结果。

  1. 传统方法

  2. ES9新特性

2.12.9 反向断言

  1. ES9支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选。

2.12.10 dotAll模式

  1. 正则表达式中 dot(.)匹配除回车外的任意单个字符,标记s改变这种行为,允许行终止符出现。


2.13 唯一值 Symbol

  1. 定义:ES6中新的原始数据类型,是JS中第7种数据类型,表示独一无二的值,类似于字符串的数据类型

  2. 特点:

    1)Symbol 的值是唯一的,用来解决命名冲突的问题

    2)Symbol 值不能与其他数据进行运算

    3)Symbol 定义的对象属性不能使用for…in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名

  3. 作用:给对象添加/创建属性(用中括号[ ]添加)

    1)如果想给对象添加属性,传统方法需要查看对象中是否已经有某种属性名,以防重名覆盖

    2)外部添加法

    3)内部添加法

  4. 内置值:除了定义自己使用的 Symbol 值以外,ES6 还提供了11个内置的 Symbol 值指向语言内部使用的方法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行。

    1)Symbol.hasInstance:当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法

    2)Symbol.isConcatSpreadable:布尔值,表示该对象用于 Array.prototype.concat()时,是否可以展开

    3)Symbol.species:创建衍生对象时,会使用该属性

    4)Symbol.match:当执行 str.match(myObject) 时,如果该属性存在,会调用它,返回该方法的返回值

    5)Symbol.replace:当该对象被 str.replace(myObject)方法调用时,会返回该方法的返回值

    6)Symbol.search:当该对象被 str.search (myObject)方法调用时,会返回该方法的返回值

    7)Symbol.split:当该对象被 str.split(myObject)方法调用时,会返回该方法的返回值

    8)Symbol.iterator:对象进行 for...of 循环时,会调用该方法,返回该对象的默认遍历器

    9)Symbol.toPrimitive:该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值

    10)Symbol.toStringTag:在该对象上面调用 toString 方法时,返回该方法的返回值

    11)Symbol.unscopables:该对象指定了使用 with 关键字时,哪些属性会被 with 环境排除

  5. description属性:用于获取Symbol的字符串描述


2.14 集合 Set

  1. 定义:ES6 提供了新的数据结构Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用扩展运算符...展开、for...of...进行遍历。

  2. 属性与方法:

    • size:返回集合的元素个数
    • add:增加一个新元素,返回当前集合
    • delete:删除元素,返回 boolean 值
    • has:检测集合中是否包含某个元素,返回 boolean 值
    • clear:清空集合,返回 undefined
  3. 应用:

    • 数组去重
    • 求交集
    • 求并集
    • 求差集

2.15 高级对象 Map

  1. 定义:ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了iterator接口,所以可以使用扩展运算符...展开、for...of...进行遍历。

  2. 属性与方法:

    • size:返回 Map 的元素个数
    • set:增加一个新元素,返回当前 Map
    • get:返回键名对象的键值
    • has:检测 Map 中是否包含某个元素,返回 boolean 值
    • delete:删除元素,指定键名
    • clear:清空集合,返回 undefine

2.16 模块化 Module

2.16.1 模块化定义

  1. 定义:模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。

  2. 优点:防止命名冲突、代码复用、高维护性。

  3. ES6 之前的模块化规范产品:

    • CommonJS => NodeJS、Browserify
    • AMD => requireJS
    • CMD => seaJS

2.16.2 模块化语法

2.16.2.1 暴露模块 export

export:用于规定模块的对外接口

  1. 分别暴露

  2. 统一暴露

  3. 默认暴露

2.16.2.2 导入模块 import

import:用于输入其他模块提供的功能(需要用 <script type="module"> </script>包裹)

  1. 通用导入:调用属性和方法时,需要用 m1.xxx、m2.xxx、m3.default.xxx

  2. 解构赋值导入:可以直接调用导入的属性和方法

  3. 简便形式:针对默认暴露,可以直接用 m3.xxx 调用default默认暴露的属性和方法

2.16.2.3 整体导入模块

整体导入模块:<script src="..." type="module"></script>

  1. 如果把需要导入的模块全部写在html下的script中,会显得很长,可以把需要导入的部分单独写成独立js入口文件,统一导入

  2. 缺点:兼容性问题,目前只有chrome等浏览器支持,并非所有浏览器都支持此方法

2.16.2.4 动态导入模块
  1. ES6导入是静态的,需要全部导入,不能实现懒加载(按需加载)。ES11可以用动态import导入,按需加载。

  2. 语法:import('xxx.js').then((module)=>{module.xxx()}),then后面返回的是promise对象,对应的就是导入的模块,可以调用其属性和方法。

2.16.3 Babel模块化转换

  1. 作用:解决其他浏览器无法整体导入模块,以及ES6无法直接导入npm模块的问题

  2. 官网:www.babeljs.cn

  3. 步骤:

    • 配置环境:一次即可
    • 编译+打包:如果代码改动,需要重新编译打包
  4. 整体导入模块:<script src="...bundle.js" type="module"></script>

2.16.4 引入npm包

  1. 安装所需的npm包:npm i jquery

  2. 使用包:

  3. 编译+打包:如果代码改动,需要重新编译打包(代码见上)

  4. 整体导入模块:<script src="...bundle.js" type="module"></script>


2.17 Promise

2.17.1 Promise的基本使用

2.17.1.1 Promise简介
  1. 抽象表达:

    • Promise 是一门新的技术(ES6 规范)
    • Promise 是 JS 中进行异步编程的新解决方案(旧方案是单纯使用回调函数)
    • 异步编程包括:fs、定时器、数据库操作、ajax
  2. 具体表达:

    • 从语法上来说: Promise 是一个构造函数
    • 从功能上来说: Promise 对象用来封装一个异步操作并可以获取其成功或失败的结果值
  3. Promise的状态 PromiseState:只有以下2种, 且一个 promise 对象只能改变一次。无论变为成功还是失败, 都会有一个结果数据

    • 成功:pending 变为 resolved/fulfilled
    • 失败:pending 变为 rejected
  4. Promise对象的值 PromiseResult

    • 成功的结果数据: value
    • 失败的结果数据: reason
  5. Promise 的基本流程:


2.17.1.2 Promise优势
  1. 指定回调函数的方式更加灵活:

    • 旧方法:必须在启动异步任务前指定
    • promise:启动异步任务 => 返回promie对象 => 给promise对象绑定回调函数(甚至可以在异步任务结束后指定/多个)
  2. 支持链式调用, 可以解决回调地狱问题:

    • 回调地狱:回调函数嵌套调用, 外部回调函数异步执行的结果是嵌套的回调执行的条件。不便于阅读、不便于异常处理。
    • 解决方案:promise 链式调用
    • 终极解决方案:async与await

2.17.1.3 Promise基本案例
  1. 定时器模拟中奖:点击按钮, 1s 后显示是否中奖(30%概率中奖)

  2. 判断时间戳是否为奇数

  3. 与fs模块结合读取文件


2.17.1.4 Promise封装功能
  1. 使用 promise 封装 fs 模块 (node.js)

  2. 使用 promise 封装基于定时器的异步

  3. 使用 promise 封装 Ajax 异步请求

2.17.1.5 util.promisify方法
  1. 第三方插件util:传入一个遵循常见错误优先的回调风格函数(即以(err,value)=>...回调作为最后一个参数),并返回一个promise版本。可以使用它来达到用promise封装功能的效果。


2.17.2 Promise API

2.17.2.1 Promise构造函数

Promise (excutor) {}:executor 会在 Promise 内部立即同步调用,异步操作在执行器中执行。

  1. executor 函数: 执行器 (resolve, reject) => {}
  2. resolve 函数: 内部定义成功时调用的函数 value => {}
  3. reject函数: 内部定义失败时调用的函数 reason => {}

2.17.2.2 Promise.prototype.then

Promise.prototype.then(onResolved, onRejected) => {}

指定用于得到成功 value 的成功回调和用于得到失败 reason 的失败回调返回一个新的 promise 对象

  1. onResolved 函数: 成功的回调函数 (value) => {}
  2. onRejected 函数: 失败的回调函数 (reason) => {}

2.17.2.3 Promise.prototype.catch

Promise.prototype.catch(onRejected) => {},then()的语法糖, 但只能指定失败的回调函数,相当于: then(undefined, onRejected)

  1. onRejected 函数: 失败的回调函数 (reason) => {}


2.17.2.4 Promise.resolve

Promise.resolve(value) => {},返回一个成功/失败的 promise 对象

  1. value: 成功的数据或 promise 对象


2.17.2.5 Promise.reject

Promise.reject(reason) => {},返回一个失败的 promise 对象

  1. reason: 失败的原因


2.17.2.6 Promise.all

Promise.all(promises) => {},返回一个新的 promise, 只有所有的 promise 都成功才成功, 只要有一个失败了就直接失败

  1. promises: 包含 n 个 promise 的数组


2.17.2.8 Promise.allSettled

Promise.allSettled(promises) => {},返回一个新的 promise, PromiseState始终为"fulfilled",PromiseResult为数组,其成员为原始数组中promise的返回对象,包含states、value或reason。

  1. promises: 包含 n 个 promise 的数组


2.17.2.7 Promise.race

Promise.race(promises) => {},返回一个新的 promise, 第一个完成的 promise 的结果状态就是最终的结果状态

  1. promises: 包含 n 个 promise 的数组


2.17.3 Promise的关键问题

  1. 如何改变 Promise 的状态?

    (1) resolve(value): 如果当前是 pending 就会变为 resolved

    (2) reject(reason): 如果当前是 pending 就会变为 rejected

    (3) 抛出异常 throw('error'): 如果当前是 pending 就会变为 rejected

  2. 一个 Promise 指定多个成功/失败回调函数, 都会调用吗?

    • 当 promise 改变为对应状态时都会调用
  3. 改变 Promise 状态和指定回调函数谁先谁后?

    (1) 都有可能, 同步任务是先改变状态、再指定回调,异步任务是先指定回调、再改变状态

    (2) 如何先改状态再指定回调?

    • 在执行器中直接调用 resolve()/reject()
    • 延迟更长时间才调用 then()

    (3) 什么时候才能得到数据?

    • 如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据
    • 如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据
  4. Promise.then()返回的新 promise 的结果状态由什么决定?

    (1) 简单表达: 由 then()指定的回调函数执行的结果决定

    (2) 详细表达:

    • 如果抛出异常, 新 promise 变为 rejected, reason 为抛出的异常
    • 如果返回的是非 promise 的任意值, 新 promise 变为 resolved, value 为返回的值
    • 如果返回的是另一个新 promise, 此 promise 的结果就会成为新 promise 的结果
  5. Promise 如何串连多个操作任务?

    (1) promise 的 then()返回一个新的 promise, 可以开成 then()的链式调用

    (2) 通过 then 的链式调用串连多个同步/异步任务

  6. Promise 异常穿透?

    (1) 当使用 promise 的 then 链式调用时, 可以在最后指定失败的回调

    (2) 前面任何操作出了异常, 都会传到最后失败的回调中处理

  7. 中断 Promise 链?

    (1) 当使用 promise 的 then 链式调用时, 在中间中断, 不再调用后面的回调函数

    (2) 办法: 在回调函数中返回一个 pendding 状态的 promise 对象


2.18 async与await

2.18.1 async函数

  1. 函数的返回值为 promise 对象

  2. promise 对象的结果由 async 函数执行的返回值决定

2.18.2 await表达式

  1. await 右侧的表达式一般为 promise 对象, 但也可以是其它的值

  2. 如果表达式是 promise 对象, await 返回的是 promise 成功的值

  3. 如果表达式是其它值, 直接将此值作为 await 的返回值

  4. await 必须写在 async 函数中, 但 async 函数中可以没有 await

  5. 如果 await 的 promise 失败了, 就会抛出异常, 需要通过 try...catch 捕获处理

2.18.3 async与await结合

  1. 使用fs读取文件内容

  2. 封装Ajax请求


第3章 Web API

API:Application Progamming Interface,应用程序接口,无需关心内部构造,直接调用即可

3.0 常用方法集锦

  1. console.dir:显示元素对象的属性和方法

  2. document.write():如果页面文档流加载完毕,再调用这句话会导致页面重绘,例:document.write('

    123
    ')

  3. window.onload=function(){}:页面加载完毕再执行JS的函数

  4. window.parent.XXX():如果存在页面嵌套(如iframe),子页面可以跳到父页面js中的方法

  5. 阻止链接<a>跳转:href=javascript:void(0)'href=javascript:;

  6. 立即执行函数:(function(){})()(function(){}())

  7. flag开关:

3.1 API基本概念

3.1.1 API简介

  1. Web API:浏览器提供的一套操作浏览器功能和页面元素的API,包括DOM、BOM
  2. 书写顺序:文档页面从上到下加载,所以先写HTML标签,<script>写到标签的最下面
  3. 常用命令:console.dir:显示元素对象的属性和方法

3.1.2 API重要概念

回调函数
  1. 定义:callback,即需要等待时间才去调用函数
  2. 定时器:setTimeout()setInterval()
  3. 注册事件中的函数,如addEventListener('click',fn)中的fn
this指向
  1. 指向window

    1)全局作用域:console.log(this)

    2)普通函数

    3)计时器

  2. 指向调用它的对象

    1)方法调用

    2)构造函数

JS执行机制
  1. JS是单线程:同一个时间只能做一件事,所有的任务需要排队执行,可能会造成阻塞、渲染不连贯

  2. 同步:前一个任务结束后再执行后一个任务,按顺序进行

    同步任务:都在主线程上执行,形成一个执行栈

  3. 异步:同时处理多个任务,目前 JS 默认是异步的

    异步任务:通过回调函数实现,放在任务队列(消息队列)中

    1)普通事件:clickresize

    2)资源加载:loaderror

    3)定时器:setTimeoutsetInterval

  4. 执行机制:先执行执行栈中的同步任务

    1)异步任务(回调函数)放到任务队列中:是先给异步进程处理,判断时间先后顺序,再放入任务队列

    2)一旦执行栈中的所有同步任务执行完毕,系统按次序读取任务队列中的异步任务,被读取的异步任务结束等待状态,进入执行栈执行

    3)事件循环(event loop):主线程不断重复获得任务、执行任务的机制

立即执行函数
  1. 定义:不需要调用,立刻能够自己执行的函数

  2. 特点:独立创建了一个作用域,里面所有的变量都是局部变量,不会有命名冲突的情况

  3. 语法:第一个括号定义参数,第二个括号既可以传参、也有调用的作用

    1)方法1:(function(){})()

    2)方法2:(function(){}())


3.2 DOM

文档对象模型 (Document Object Model) 是HTML和XML文档的编程接口,它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构、样式和内容。

3.2.1 DOM简介

  1. 文档:document,一个页面即一个文档
  2. 元素:element,页面中所有标签都是元素
  3. 节点:node,网页中所有内容都是节点,如标签、属性、文本、注释等
  4. 对象:DOM把文档、元素、节点都看做是对象

3.2.2 获取元素

  1. document.getElementById(id名):根据id获取元素

    1)语法:var element = document.getElementById(id)

    2)参数:id 是大小写敏感的字符串

    3)返回:一个元素对象

  2. document.getElementsByTagName(标签名):根据html标签获取元素

    1)语法:var element = document.getElementsByTagName(标签名)

    2)返回:带有指定标签名对象的集合,以伪数组的形式存储(HTMLCollection(n))

    3)获取父元素中的子元素

    • 方法1:element.getElementsByTagName('标签名'),父元素必须是指定的单个元素

    • 方法2:给父元素指定id,配合getElementById使用

  3. document.getElementsByClassName(类名):根据class获取元素

    1)语法:var element = document.getElementsByClassName(类名)

    2)返回:带有指定类名对象的集合,以伪数组的形式存储

  4. document.querySelector(选择器名):根据选择器名获取元素(仅返回第一个元素)

    1)语法:var element = document.querySelector(选择器名),选择器要加符号(eg: .box,#nav)

    2)返回:根据指定选择器返回第一个元素对象

    3)注意:如果直接写标签选择器(如:li),前面不用加符号,也是选出第一个标签元素

  5. document.querySelectorAll(选择器名):根据选择器名获取元素(返回全部元素)

    1)返回:指定选择器的所有元素对象集合(NodeList(n))

    2)可以配合使用:选中父元素中所有子元素的集合

  6. 特殊元素:

    1)body元素:document.body

    2)html元素:document.documentElement


3.2.3 事件

3.2.3.1 事件介绍
事件三要素
  1. 事件源:事件被触发的对象,如按钮
  2. 事件类型:如何触发事件,如鼠标点击/经过
  3. 事件处理程序:通过一个函数赋值的方式完成
事件执行步骤
  1. 获取事件源

  2. 绑定事件(注册事件)

  3. 添加事件处理程序(函数赋值)

DOM事件流:捕获与冒泡
  1. 定义:事件流描述的是从页面中接收事件的顺序,事件发生时会在元素节点之间按照特定的顺序传播,传播过程称为DOM事件流

  2. 三阶段:

    1)捕获阶段:由网景提出,由DOM最顶层节点开始,逐级向下传播到最具体的元素接收的过程

    • 如果 addEventListener 第三个参数是 true,那么则处于捕获阶段
    • 从外往里执行:document -> html -> body -> father -> son

    2)目标阶段

    3)冒泡阶段:由IE提出,事件开始时由最具体的元素接收,逐级向上传播到DOM最顶层节点的过程

    • onclick、attachEvent只能得到冒泡阶段
    • 如果 addEventListener 第三个参数是 false 或省略,那么则处于冒泡阶段
    • 从里往外执行:son -> father ->body -> html -> document

     

  3. JS代码中只能执行捕获、冒泡其中之一的阶段

  4. 有些事件没有冒泡:onblur、onfocus、onmouseenter、onmouseleave


3.2.3.2 事件对象
基本概念
  1. event 就是一个事件对象,写到侦听函数的小括号里面,当形参来看

  2. 事件对象只有有了事件才会存在,是系统自动创建的,不需要传递参数

  3. 事件对象是事件的一系列相关数据的集合,如鼠标点击包含了鼠标相关信息(坐标),键盘事件包含键盘事件信息(按键)

  4. 事件对象可以自己命名,如 event、evt、e

  5. 事件对象也有兼容性问题:ie678 通过 window.event 兼容性的写法

属性和方法
  1. e.target:返回触发事件的对象(标准)

    1)e.target:返回的是触发事件的对象(元素),点击了哪个元素,就返回哪个元素

    2)this:返回的是绑定事件的对象(元素),哪个元素绑定了这个点击事件,那么就返回谁

    3)e.currentTarget:和this效果相同,但是不兼容IE6-8,不如直接用this

  2. e.srcElement:返回触发事件的对象(非标准,IE6-8使用)

  3. e.type:返回事件类型,如:click、mouseover,前面不带on

  4. 阻止冒泡:

    1)e.stopPropagation():标准写法

    2)e.canceBubble=true:非标准,IE6-8使用

     

  5. 阻止默认事件:如不让链接跳转等

    1)e.preventDefault():标准方法

    2)e.returnValue:非标准方法,IE6-8使用

    3)return false:也能阻止默认行为,没有兼容性问题,但return后面的代码不执行,且只限于传统的注册方式

  6. e.persisted:返回true代表页面从是缓存中取出的,返回false代表不是从缓存取出的,常与pageshow事件搭配使用


3.2.3.3 注册事件
  1. 传统方式:

    1)以on开头的事件,如:onclick

    2)特点:唯一性,同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数

  2. addEventListener():方法监听注册

    1)语法:eventTarget.addEventListener(type,listener,[,useCapture])

    2)参数:

    • type:事件类型字符串,必须加引号,如:click, mouseover,前面无需加on
    • listener:事件处理函数,事件发生时,会调用该监听函数
    • userCapture:DOM事件流方向,可选,布尔值,默认false(冒泡阶段)
  3. attachEvent():方法监听注册,IE9之前的方法

    1)语法:attachEvent(eventNameWithOn, callback)

    2)参数:

    • eventNameWithOn:事件类型字符串,必须加引号,如:onclick, onmouseover,前面需要加on
    • callback:事件处理函数,目标出发事件时调用回调函数
  4. 兼容性处理函数:


3.2.3.4 删除事件
  1. eventTarget.onclick = null:传统方式,需要写到函数的末尾

  2. removeEventListener():方法监听注册

    1)语法:eventTarget.removeEventListener(type,listener[,useCapture])

    2)需要移除的事件函数不能是匿名函数,否则无法移除,要把removeEventListener写到需要删除的函数末尾

  3. deachEvent():方法监听注册,IE9之前的方法

    1)语法:deachEvent(eventNameWithOn,callback)

    2)同样写到需要删除函数事件的末尾


3.2.3.5 事件委托
  1. 定义:不给每个子节点单独设置事件监听器,而将其设置在父节点上,利用冒泡原理影响设置每个子节点

  2. 作用:只操作一次DOM,提高程序性能


3.2.3.6 鼠标事件
事件动作
  1. click:点击左键触发

  2. dblclick:双击左键触发

  3. 鼠标经过触发:

    • mouseover:经过自身盒子触发,经过子盒子还会触发
    • mouseenter:仅经过自身盒子触发,因为它不冒泡
  4. 鼠标离开触发:

    • mouseout:经过自身盒子触发,经过子盒子还会触发
    • mouseleave:仅经过自身盒子触发,因为它不冒泡
  5. focus:获得鼠标焦点触发

  6. blur:失去鼠标焦点触发

  7. mousemove:鼠标移动触发

  8. mouseup:鼠标弹起触发

  9. mousedown:鼠标按下触发

  10. contextmenu:右键菜单

  11. selectstart:选中文字

  12. 双击禁止选中文字

事件对象:MouseEvent
  1. e.clientX:鼠标相对浏览器可视区的X坐标

  2. e.clientY:鼠标相对浏览器可视区的Y坐标

  3. e.pageX:鼠标相对于文档页面的X坐标(IE9+支持)

  4. e.pageY:鼠标相对于文档页面的Y坐标(IE9+支持)

  5. e.screenX:鼠标相对于电脑屏幕的X坐标

  6. e.screenY:鼠标相对于电脑屏幕的Y坐标

手动调用事件
  1. element.click():点击事件

3.2.3.7 键盘事件
事件动作
  1. keyup:某个按键松开时触发,注意:在文本框中的特点:事件触发时,文字还没落入文本框,所以最好用keyup

  2. keydown:某个按键按下时触发

  3. keypress:某个按键按下时触发,但不能识别功能键,如ctrl、shift、箭头等

事件对象:KeyboardEvent
  1. e.keyCode:返回按键的ASCII值,其中keyup、keydown不区分大小写,keypress区分大小写

3.2.3.8 表单事件
  1. checkbox复选框:change:状态变化

  2. input输入框:

    1)select():文本框里面的文字处于选定状态

    2)onfocusonblur:获得、失去焦点

  3. form表单域:reset():重置,清空内容

  4. 文字选择框:

    1)结构:<input type="file" accept="..." />,accept代表可以选择的文件类型,如image/png, image/jpeg

    2)change:绑定change事件,意味着文件选择框被激活

    3)e.target.files:文件列表

    4)e.target.files[0]:单个文件

    5)URL.createObjectURL(file):文件转化为路径


3.2.4 元素操作

3.2.4.1 元素内容
  1. element.innerText:从起始位置到终止位置的内容,去除html标签、空格、换行

    1)非标准,IE推出的

    2)不识别html标签,如果替换内容有标签会按原型打印出来

  2. element.innerHTML:从起始位置到终止位置的内容,保留html标签、空格、换行

    1)W3C标准,推荐使用

    2)识别html标签,可用html标签给文字添加效果

    3)创建新元素

    • 拼接法:大量创建标签效率低下,因为字符串拼接占用内存太多

    • 数组法:创建空数组,用push方法添加,可以提升创建效率

3.2.4.2 元素属性
修改表单属性
  1. 表单常用属性:type、value、checked、selected、disabled

  2. 内容:value,无法用innerHTML获取/修改内容,要通过value修改,例:input.value = XXX

  3. 禁用:disabled,例btn.disabled = true,点击按钮后无法再次点击,如果是通过btn.onclick定义的事件,可以用this.disabled = ture

设置元素属性
  1. element.属性:通过函数/流程控制,直接对元素属性进行设置

  2. element.setAttribute(属性名,属性值):可以自定义元素属性,目的:保存并使用数据,有些数据可以直接保存在页面中,无需从数据库中调用

  3. H5自定义属性:

    1)格式:data-属性名=属性值,例:<div data-index="1" >

    2)目的:消除歧义,便于区分内置属性和自定义属性

获取元素属性
  1. element.属性:只能获取元素内置属性

  2. element.getAttribute(属性名):可以获取自定义属性

  3. element.dataset.属性名element.dataset[属性名]:H5自定义属性

    1)dataset:是一个集合(DOMStringMap),里面存放了所有以data开头的自定义属性,获取时属性名前无需再加'data-'

    2)自定义属性里面有多个" - "链接的单词,获取的时候采取驼峰命名法,例:属性: data-list-name,获取: listName

    3)例:div.dataset.listName、div.dataset['listName']

移除元素属性
  1. element.removeAttibute(属性名)
3.2.4.3 元素样式
  1. element.style.样式属性:行内样式操作,产生的是行内样式,权重较高

  2. element.className = '新类名':类名样式操作

    1)适用于需要修改样式较多的情况,先在css中写一个新类名,然后达到修改元素类名的效果

    2)会直接更改元素的类名,覆盖原先的类名

    3)如果希望保留原类名,可以在原类名后加空格,再写新类名

  3. element.classList:获取元素类名,返回DOMTokenList

    1)增加类名:element.classList.add(类名),不会覆盖原有类,类名不用加“.”

    2)删除类名:element.classList.remove(类名)

    3)切换类名:element.classList.toggle(类名),若类名存在则删除,若类名不存在则添加上

3.2.4.4 创建元素
  1. document.write():如果页面文档流加载完毕,再调用这句话会导致页面重绘,例:document.write('
    123
    ')
  2. window.onload=function(){}:页面加载完毕再执行JS的函数
3.2.4.5 常用方法
排他思想
换肤效果
表格操作
  1. 表格变色

  2. 表格选项框全选反选

Tab栏切换内容
  1. tab栏选中效果:排他算法

  2. 底部内容区域跟随变化:通过对应tab栏的index编号进行索引,设置display属性(也用到了排他算法)


3.2.5 Node操作

  1. 特点:相对DOM获取元素而言,节点操作利用父子兄节点关系获取元素,逻辑性强,但是兼容性差

  2. 基本属性:nodeType(节点类型)、nodeName(节点名称)、nodeValue(节点值)

  3. 节点类型:nodeType

    1)Element:元素节点

    2)Attribute:属性节点

    3)Text:文本节点

    4)CDATA Section

    5)Entity Reference

    6)Entity

    7)Processing Instrucion

    8)Comment

    9)Document

    10)Document Type

    11)Document Fragment

    12)Notation

3.2.5.1 父节点
  1. 语法:node.parentNode

  2. 就近原则:得到的是离元素最近的父级节点,如果找不到父节点就返回为 null

  3. 如果存在页面嵌套(如iframe),子页面可以跳到父页面js中的方法,如:window.parent.XXX()

3.2.5.2 子节点
  1. 语法:

    1)parentNode.childNodes:指定节点的子节点的集合(包含元素节点、文本节点等),形式为 NodeList(x)

    2)parentNode.children:返回所有的子元素节点(仅有元素节点),形式为HTMLCollection(x),指定子元素节点:parentNode.children[i]

  2. 获取第一个子节点:

    1)parent.firstChild:第一个子节点(所有类型)

    2)parent.firstElementChild:第一个元素子节点,IE9上才支持

    3)parentNode.children[0]:第一个元素子节点,兼容性较好

  3. 获取最后一个子节点:

    1)parent.lastChild:最后一个子节点(所有类型)

    2)parent.lastElementChild:最后一个元素子节点,IE9上才支持

    3)parentNode.children[parentNode.children.length-1]:最后一个元素子节点,兼容性较好

  4. 案例:下拉菜单

3.2.5.3 兄弟节点
  1. 下一个兄弟节点

    1)node.nextSibling:获取下一个兄弟节点(所有类型)

    2)node.nextElementSibling:获取下一个兄弟元素节点

  2. 上一个兄弟节点:

    1)node.previousSibling:获取下一个兄弟节点(所有类型)

    2)node.previousElementSibling:获取下一个兄弟远元素节点

3.2.5.4 创建节点
  1. document.createElement('tagName'):动态创建节点

3.2.5.5 添加节点
  1. node.appendChild(child):将一个节点添加到指定父节点的子节点列表末尾,像CSS的after伪元素

  2. node.insertBefore(child, 指定元素):将一个节点添加到指定元素之前

  3. node.insertAdjacentHTML(位置, 字符串元素):与appendChild的区别在于,此方法支持直接在父元素插入以字符串形式定义的新元素

    1)beforebegin:元素自身的前面

    2)afterbegin:插入元素内部第一个子节点之前

    3)beforeend:插入元素内部最后一个子节点之后

    4)afterend:元素自身后面

3.2.5.6 删除节点
  1. node.removeChild(child):删除父节点下的子节点

  2. 案例:删除留言:制作删除按钮,阻止链接<a>跳转:href = 'javascript: void(0);' 或 'javascript:;'

3.2.5.7 复制节点
  1. node.cloneNode():括号内为空或false,浅拷贝,只复制标签不复制里面的内容

  2. node.cloneNode(true):括号内为true,深拷贝,复制标签和内容

3.2.5.8 动态创建表格
  1. 创建行:for循环储存数据的数组,有几条数据创建几行

  2. 创建单元格:for循环对象,对象有几个属性创建几个单元格,如果需要额外添加单元格(如:删除按钮),则再单独创建单元格

  3. 删除按钮<a>:tbody.removeChild( this.parentNode.parentNode),即删除<a>的父元素<td>的父元素<tr>


3.3 BOM

浏览器对象模型(Browser Object Model),提供独立于内容而与浏览器窗口进行交互的对象,核心对象是window。

3.3.1 BOM简介

  1. BOM由一系列相关的对象构成,每个对象提供了很多方法和属性

  2. BOM缺乏标准,JS标准是ECMA,DOM标准是W3C,BOM是网景浏览器标准的一部分,兼容性较差

  3. 结构:window

    • document
    • location
    • navigation
    • screen
    • history

3.3.2 Windows对象

  1. 是浏览器的顶级对象,具有双重角色
  2. 是JS访问浏览器窗口的一个接口
  3. 是一个全局对象,定义在全局作用域中的变量、函数,都会变成windows对象的属性和方法
3.3.2.1 Windows属性
  1. window.name:窗口名字,用于为超链接和表单设置目标(targets)

  2. window.devicePixelRatio:物理像素比(1px能显示的物理像素点的个数)

  3. window.innerWidth:当前窗口大小

  4. 页面滚动:

    1)window.pageYOffset:页面被卷去的头部大小(无单位)(IE9+支持)

    2)window.pageXOffset:页面被卷去的左侧大小(无单位)(IE9+支持)

    3)旧版兼容:

    • 已声明DTD(即<!DOCTYPE html>):document.documentElement.scrollTop
    • 未声明DTD:document.body.scrollTop
3.3.2.2 Windows方法
窗口加载: load
  1. load

    1)定义:当文档内容完全加载会触发该事件(包括图像、脚本、CSS等),可以把JS放在head里

    2)触发动作:<a>、F5刷新、前进后退按钮

    3)window.onload:传统注册事件,只能写一次,如果有多个以最后一个为准

    4)window.addEventListener('load',fn):方法监听注册,可以写多个

    5)document.addEventListener('DOMContentLoaded',fn):仅当DOM加载完成时触发,包括JS,但不包括图片、CSS、flash等(IE9+支持),适用于多媒体较多的网页,不耽误用户操作其他按钮

  2. window.addEventListener('pageshow',fn)

    1)火狐浏览器具有“往返缓存”的特点,使用后退按钮返回页面时,如果使用load不会重新加载页面,此时需要pageshow,页面先执行其中的回调函数

    2)页面显示时触发,无论页面是否来自于缓存,会在load事件后触发,可配合使用 e.persisted 判断是否是缓存中的页面

窗口大小: resize
  1. window.onresize

  2. window.addEventListener('resize',fn)

窗口滚动: scroll
  1. window.scroll(x,y):里面数值不加单位
定时器: setTimeout
  1. setTimeout(回调函数,[延迟的毫秒数]):仅执行一次

    1)调用函数可以直接写函数,还可以写函数名或 '函数名()'

    2)页面中可能有很多的定时器,经常给定时器加名字

    3)案例:页面广告自动隐藏

    4)停止定时器:clearTimeout(定时器名称)

  2. setInterval(回调函数,[延迟的毫秒数]):重复调用一个函数,每隔这个时间就调用一次回调函数

    1)停止定时器:clearInterval(定时器名称)

    2)注意:如果定时器被写入了注册事件函数内部的匿名函数,需要在外面声明一个与定时器同名的全局变量,令其为null

本地储存: localStorage
  1. 特性:

    1)数据储存在用户浏览器中

    2)设置/读取方便,页面刷新不丢失数据

    3)容量大,sessionStorage存5M、localStorage存20M

    4)查看数据:点击F12中的应用,本地储存空间/会话储存空间

  2. 储存与读取:

    1)只能存储字符串,可以将对象JSON.stringify()编码后储存(格式为字符串)

    2)读取数据时,也要先用JSON.parse()转化后才能使用(格式为数组)

  3. sessionStorage:会话储存,生命周期:关闭浏览器窗口

    1)sessionStorage.setItem(key,value):存储数据

    2)sessionStorage.getItem(key):获取数据

    3)sessionStorage.removeItem(key):删除数据

    4)sessionStorage.clear():删除所有数据

  4. localStorage:本地储存,生命周期:永久,除非手动删除

    1)可以多窗口/页面共享(同一浏览器可以共享)

    2)方法:与sessionStorage相同

  5. 案例:记住用户名

  6. 案例:ToDoList

    1)页面刷新内容不会丢失:本地存储localStorage

    2)文本框输入内容,按下回车生成代办事项:$("element").on("keydown",function(event){if(event.keyCode===13){...}})

    3)先从localStorage取数据,再将新数据push添加到数组,再存储给localStorage

    4)点击删除按钮,内容消失:

    5)点击待办事项复选框,把当前数据添加到已完成事项中:点击之后获取本地存储数据,修改done属性值为当前复选框checked状态

    6)点击已完成事项复选框,把当前数据添加到待办事项中


3.3.3 location对象

  1. 用途:用于获取或设置窗体的URL,可以解析URL

  2. URL:统一资源定位符(Uniform Resource Locator),互联网上每个文件都有唯一的URL

    1)protocol:通信协议,如http、https、maito等

    2)host:主机(域名)

    3)port:端口号,可选,省略时使用方案默认端口,如http默认端口为80

    4)path:路径,表示主机上的一个目录或文件地址

    5)query:参数,以键值对的形式通过&符号分隔开来

    6)fragment:片段,#后面内容常见于链接锚点

  3. 属性:

    1)location.href:获取或设置整个URL

    2)location.host:返回主机(域名)

    3)location.port:返回端口号,如果未写返回空字符串" "

    4)location.pathname:返回路径,对应的path

    5)location.search:返回参数,对应的query,注意:如果参数中带有中文,需要用decodeURIComponent()解码

    6)location.hash:返回片段,对应的fragment

  4. 方法:

    1)location.assign():与href相同,可以跳转页面,可以后退

    2)location.replace():替换当前页面,但不记录历史,不能后退页面

    3)location.reload():重新加载页面,相当于刷新按钮/F5,如果参数为true,强制刷新Ctrl+F5(不读取缓存)


3.3.4 navigator对象

  1. navigator.userAgent:适配不同设备,如果是移动端,可以自动跳转到H5页面;返回由客户端发送服务器的user-agent头部的值


3.3.5 history对象

  1. 定义:与浏览器历史进行交互,包含用户访问过的URL

  2. 方法:

    1)back():后退

    2)forward():前进

    3)go(参数):前进后退功能,参数为1即前进1个页面,参数为-1即后退1个页面


3.4 网页特效

3.4.1 offset偏移量

  1. 属性:只读属性,不可赋值,无法更改元素样式

    1)element.offsetParent:返回作为该元素带有定位的父级元素,如过父级元素没有定位返回body

    2)element.offsetTop:返回元素相对带有定位父元素上方的偏移

    3)element.offsetLeft:返回元素相对带有定位父元素左边框的偏移

    4)element.offsetWidth:返回自身包括padding、边框、内容区的宽度,返回数值不带单位

    5)element.offsetHeight:返回自身包括padding、边框、内容区的高度,返回数值不带单位

  2. 与sytle的区别:想获取元素大小位置用offset,想改变元素样式用style

    1)offset可获取任意样式表样式值,style只能得到行内样式表的样式值

    2)offset获得值没有单位,style获得值有单位

    3)offsetWidth 包含 padding+border+width,style.width只包含width

    4)offsetWidth是只读属性不能赋值,style.width可读写属性可以赋值

  3. 案例1:计算鼠标在盒子内的坐标

  4. 案例2:模态框拖拽效果(mousedown开始拖拽事件,mouseup取消拖拽监听事件)

  5. 案例3:电商详情页放大镜

    1)鼠标经过橱窗preview_img,显示/隐藏遮挡层 mask 和放大镜大盒子 big

    2)鼠标移动时,遮挡层mask跟着鼠标走

    3)鼠标移动时,大图片也跟随mask移动


3.4.2 client可视区

  1. event.clientTop:返回元素上边框大小

  2. event.clientLeft:返回元素左边框大小

  3. event.clientWidth:返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位

  4. event.clientHeight:返回自身包括padding、内容区的高度,不含边框,返回数值不带单位


3.4.3 scroll滚动区

  1. 属性:

    1)event.scrollTop:返回被卷去的上侧距离(无单位)

    2)event.scrollLeft:返回被卷去的左侧距离(无单位)

    3)event.scrollWidth:返回自身实际宽度,不含边框(无单位)

    4)event.scrollHeight:返回自身实际高度,不含边框(无单位)

  2. 事件:scroll

    1)定义:只要滚动条发生变化,就会触发该事件

    2)语法:element.addEventListener('scroll', fn)

  3. 案例:淘宝粘性固定侧边栏

    1)原理:计算页面被卷去的头部大小,滚动到指定位置后,侧边栏变为固定定位

    2)注意:侧边栏变成固定定位时,需要修改对应的距离顶部值,不然会出现向下跳的情况,返回时也需要修改回原值


3.4.4 动画函数封装

  1. 原理:通过定时器setInterval()不断移动盒子位置,附加定时器停止的条件

    1)通过函数封装动画函数,里面的定时器名字最好用obj.timer的方式命名,同时要先清除旧定时器,可以避免重复调用定时器(后果是越来越快)

    2)注意:盒子有绝对定位才能动起来

  2. 缓动动画:让盒子每次移动距离变小,速度就会慢下来

    1)算法:步长=(目标值-当前位置)/n份数

    2)除法计算步长容易出现小数问题,需要转换为整数:step = step > 0 ? Math.ceil(step) : Math.floor(step);

    3)由于步长可以为负数,所以算法可以直接实现倒退效果

    4)回调函数:如果想让元素在动画结束后执行某函数,可以将回调函数写到定时器结束语句后

  3. 插件:animate

3.4.5 轮播图特效

轮播图插件:swiper

  1. 轮播图片:

    1)ul>li放轮播图片(最后需要复制一个第一张图),共n+1张图

    2)ul超大宽度,li在内浮动,使ul可以装下所有图

    3)触发动画时,ul运动,li不动

    4)自动播放:计时器触发右箭头点击事件,鼠标移入后清除计时器

  2. 底部圆点:

    1)ol>li放小圆点,使用createElement创建圆点

    2)添加index属性,代表图片编号:li.setAttribute('index',i)

    3)用排他算法,令被选中的圆点具有突出效果

    4)圆点索引变量:circle

    5)同步左右箭头索引变量:num

  3. 左右箭头:

    1)鼠标移动进轮播图主区域才显示箭头,离开时箭头消失

    2)走到最前/最后时修改ul的left值,控制图片看起来像无缝衔接

    3)箭头索引变量:num

    4)同步底部圆点索引变量:circle

  4. 节流阀:

    1)作用:在轮播图中,防止连续点击造成图片滚动过快,使用节流阀控制速度

    2)算法:声明全局变量flag=true,if判断flag条件执行动画,先令flag=false,然后在动画函数传参使flag=true

  5. 插件swiper

3.4.6 返回顶部

  1. 原理:将缓动动画函数中的 obj.offsetLeft 改为 window.pageYOffset

  2. 动作:window.scroll(0, window.pageYOffset + step)

  3. 调用:animate(window, 0)


3.4.7 筋斗云

  1. 鼠标经过li,筋斗云跟到当前li:mouseenter --> animate(cloud, this.offsetLeft)

  2. 鼠标离开li,筋斗云恢复原位:mouseleave --> animate(cloud, current)

  3. 鼠标点击li,筋斗云留在当前li:click --> current = this.offsetLeft


3.4.8 移动端特效

3.4.8.1 触摸屏幕
  1. 事件动作:

    1)touchstart:手指获取元素

    2)touchmove:手指移动元素

    3)touchend:手指离开元素

  2. 事件对象:

    1)e.touches:正在触摸屏幕的所有手指的列表

    2)e.targetTouches:正在触摸当前DOM元素上的手指列表

    3)e.changedTouches:手指状态发生改变的列表

  3. click事件延迟300ms:

    1)原因:由于移动端双击手指可以放大/缩小屏幕,在第一次点击后的300ms内如果有第二次点击,则会放大屏幕

    2)解决方案:

    • 禁用缩放:
    • 自己定义函数tap:如果手指触摸和离开时间小于150ms算作点击,但每次只能添加一个元素,非常麻烦
    • fastclick.js插件:引入即可,按官方文档用法调用
3.4.8.2 拖动元素
  1. touchstart:初始坐标

    1)手指初始坐标:

    2)元素初始坐标:

  2. touchmove:移动距离

    1)手指移动距离

    2)元素移动距离

    3)阻止屏幕滚动默认行为:e.preventDefault()

3.4.8.3 移动端轮播图
  1. 图片索引:index,由于ul一开始就往右移动了一格,最左侧的复制最后一张图被隐藏,这张图没有索引

  2. 轮播图片:

    1)ul>li放图片,第一张前复制最后一张图,最后一张图复制第一张图,共n+2张图

    2)在移动端中,装图片的li要用百分比表示,如有5张图,li宽度为20%,此时才能设置img宽度100%,不然图片会以ul宽度为参考溢出屏幕

    3)利用CSS3过渡+位移:transition、transform

    4)移动距离:var translatex = -index * w;

  3. 无缝滚动:

    1)等图片滚动完毕后在判断,即过渡完判断

    2)监听过渡完成的事件:transitionend

    3)到最后一张图:若index>=ul.length-2,index恢复为0,取消transition='none',translateX归位

    4)手指在第一张图往前划:若index<0,index恢复为ul.length-3,取消transition='none',translateX归位

  4. 圆点跟随:利用classList添加/删除类名选择器

  5. 手指滑动轮播图:

    1)ul添加touchstart事件,获取手指初始X坐标,并停止计时器

    2)ul添加touchmove事件,获取手指移动距离,移动ul,并取消过渡效果transition

    3)e.preventDefault():阻止滚动屏幕默认行为

    4)添加flag=false全局变量,只有当手指滑动事件发生后,使flag=ture,便于后面手指松开效果触发的判断

  6. 手指离开图片回弹/跳转:

    1)ul添加touchend事件,判断盒子移动距离的绝对值Math.abs(moveX)

    • 大于某值:跳转

      • 右划往左走:moveX>0:index--
      • 左划往右走:moveX<0,index++
    • 小于某值:回弹

      • index不变
      • 利用CSS3过渡+位移:transition、transform

    2)利用flag判断是否为手指滑动了图片再触发事件,而不是滑动了其他地方

    3)重新启动定时器

3.4.8.4 视频插件
  1. zy.media.js:可以解决不同浏览器之间视频播放器样式不同的情况


第4章 jQuery

官网:jquery.com

4.1 jQuery基本概念

4.1.1 jQuery简介

  1. JS库:是一个封装好的特定的集合(方法和函数),如animate、hide、show等
  2. 常见的JS库:jQuery、Prototype、YUI、Dojo、Ext JS、移动端的zepto
  3. jQuery的意思是查询JS库,把JS中的DOM操作进行了封装,可以快速查询使用里面的功能

4.1.2 入口函数

  1. 作用:等待页面DOM加载完毕执行代码,相当于DOMContentLoaded

  2. 顶级对象$$是jQuery的别称,可以用jQuery代替$符号,$也是jQuery的顶级对象,相当于window

  3. 语法:$(document).ready(function(){...})$(function() { ... })

  4. 多库共存:

    1)若$符号冲突,使用jQuery代替$

    2)noConflick():让jquery释放对$的控制权,自定义一个符号或名称


4.1.3 jQuery对象

  1. DOM对象:用原生JS获取的对象,如:document.querySelector('div'),只能使用原生JS的属性和方法

  2. jQuery对象:用jQuery方式获取过来的对象,利用$包装DOM元素(w.fn.init(n)),如:$(div),只能使用 jQuery方法

  3. DOM转JQ:

    1)DOM对象:$('element'),里面有引号

    2)用原生JS获取来的DOM对象:$(object),里面没有引号

  4. JQ转DOM:

    1)$('element')[index]

    2)$('element').get(index)


4.1.4 jQuery方法

  1. index():获取当前元素的索引值

    1)如果只有一层嵌套,$(this).index()可以获取当前元素索引

    2)如果有多层嵌套,$(this).index()无法获取当前元素索引,返回值0

  2. toFixed(n):保留n位小数

  3. hover([over,] out):鼠标事件

    1)第一个位置over(可选):相当于mouseenter触发的函数

    2)第二个位置out:相当于mouseleave触发的函数

    3)注意:如果里面只写一个函数,鼠标经过、离开都会触发这个函数

  4. change(fn{...}):表单事件,checkbox中checked属性发生变化的事件


4.2 jQuery API

4.2.1 jQuery选择器

语法:$("选择器")

4.2.1.1 基础选择器
  1. ID选择器:$("#id")

  2. 全选择器:$("*")

  3. 类选择器:$(".class")

  4. 标签选择器:$("div")

  5. 并集选择器:$("div,p,li")

  6. 交集选择器:$("li.current")

  7. 子代选择器:$("ul>li"),选中最近一级子元素

  8. 后代选择器:$("ul li"),选中全部子元素

4.2.1.2 筛选选择器
  1. :first:获取第一个元素,例:$("li:first")

  2. :last:获取最后一个元素,例:$("li:last")

  3. :eq(index):获取到的元素中索引号为index的元素,例:$("li:eq(2)")

  4. :odd:获取到的元素中索引号为奇数的元素,例:$("li:odd")

  5. :even:获取到的元素中索引号为偶数的元素,例:$("li:even"):checked:获取被选中的元素(如应用在checkbox)

4.2.1.3 筛选方法
  1. parent():查找最近一级父元素,例:$("li").parent()

  2. children(selector):查找最近一级子元素,例:$("ul").children("li"),相当于$("ul>li")

  3. find(selector):后代选择器,包含所有孩子,例:$("ul").find("li"),相当于$("ul li")

  4. siblings(selector):查找兄弟节点,不包括自身,例:$(".first").siblings("li")

  5. nextAll([expr]):查找当前元素之后所有的同辈元素,例:$(".first").nextAll()

  6. prevtAll([expr]):查找当前元素之前所有的同辈元素,例:$(".last").prevtAll()

  7. hasClass(class):检查当前元素是否含有某个特定类,返回true,例:$("div").hasClass("protected")

  8. eq(index):等同于:eq(index),例:$("li").eq(2),相当于$("li:eq(2)")

     


4.2.2 jQuery样式操作

隐式迭代:遍历内部DOM元素的过程,不再需要for循环修改样式了

4.2.2.1 CSS方法
  1. 只写属性名,返回属性值:$('element').css('属性')

  2. 修改单个样式:$('element').css('属性', '值')

    1)属性名一定要加引号

    2)属性值如果是数字不用加引号和单位

  3. 以对象形式修改多个样式:$('element').css({属性1:值1, 属性2:值2, ...})

    1)属性名不用加引号,复合属性必须用驼峰命名法

    2)属性值如果不是数字需要加引号

4.2.2.2 类样式方法
  1. 添加类:$("element").addClass("classname"),不影响原类名,类似JS的classList操作,而原生JS的element.className会覆盖原类名

  2. 删除类:$("element").removeClass("classname")

  3. 切换类:$("element").toggleClass("classname"),若类名存在则删除,若类名不存在则添加上

  4. 案例:Tab栏切换


4.2.3 jQuery动态效果

4.2.3.1 显示隐藏
  1. show(speed,callback):显示

  2. hide(speed,callback):隐藏

  3. togggle(speed,callback):切换

4.2.3.2 滑动
  1. slideDown(speed,callback):下滑,一般和display: none配合

  2. slideUp(speed,callback):上滑,一般和display: none配合

  3. slideToggle(speed,callback):切换滑动

4.2.3.3 淡入淡出
  1. fadeIn(speed,callback):淡入

  2. fadeOut(speed,callback):淡出

  3. fadeToggle(speed,callback):淡入淡出切换

  4. fadeTo(speed,opacity,[easing],callback):修改透明度,速度和透明度参数必须写

4.2.3.4 效果函数参数
  1. speed:动画速度

    1)预设字符:slow、normal、fast

    2)毫秒数值:如1000,即为1秒

  2. easing:切换效果

    1)swing:先快再慢(默认)

    2)linear:匀速运动

4.2.3.4 动画停止排队
  1. 语法:stop()

  2. 作用:如果不加stop(),鼠标多次经过触发按钮的动画事件,会反复执行

  3. 写到效果/动画函数的前面

4.2.3.5 自定义动画
  1. 语法:animate(params,[speed],[easing],[callback]),params:想要更改的样式属性,以对象形式传递

  2. 案例:王者荣耀手风琴效果


4.2.4 jQuery属性操作

  1. prop()

    1)获取固有属性:prop("属性")

    2)设置固有属性:prop("属性", "属性值")

  2. attr()

    1)获取自定义属性:attr("属性"),类似原生JS中的getAttribute()

    2)设置自定义属性:attr("属性","属性值"),类似原生JS中的setAttribute()

  3. data()

    1)设置缓存属性:data("属性","属性值"),缓存在内存,浏览器刷新后消失

    2)获取缓存属性:data("属性"),注意:获取H5定义的“data-属性名”不用加“data-"


4.2.5 jQuery文本属性

  1. 获取设置文本内容:text(),相当于原生JS的innerText

  2. 获取设置元素内容:html(),相当于原生JS的innerHTML

  3. 获取设置表单值:val(),例:清空表单值:$('element').val('')


4.2.6 jQuery元素操作

4.2.6.1 遍历元素
  1. 隐式迭代(默认):只能统一修改样式,无法差异化

  2. 语法1:$("element").each(function(index, domEle){...})

    1)index:索引号(JQ已自动编号)

    2)domEle:每个DOM元素对象,不是JQ对象

  3. 语法2:$.each($("element"),function(index, domEle){...})

    1)区别:用于遍历、处理数据

    2)如果element是对象,index输出属性名,domEle输出属性值

4.2.6.2 创建元素
  1. $("html标签"):例:$("
  2. 我是后来创建的li
  3. ")
4.2.6.3 添加元素
  1. 内部添加:

    1)添加到最前面:$("element").prepend(jQuery元素)

    2)添加到最后面:$("element").append(jQuery元素)

  2. 外部添加:

    1)添加到前面:$("element").before(jQuery元素)

    2)添加到后面:$("element").after(jQuery元素)

  3. 删除元素:

    1)删除匹配的元素:$("element").remove()

    2)删除匹配的元素里面的子节点:$("element").empty()

    3)清空匹配的元素内容:$("element").html("")


4.2.7 jQuery大小操作

  1. width() / height():元素本身宽、高

  2. innderWidth() / innerHeight():包含padding

  3. outerWidth() / outerHeight():包含padding、border

  4. outerWidth(ture) / outerHeight(ture):包含padding、border、margin


4.2.8 jQuery位置操作

  1. offset():元素相对于文档的偏移坐标,与父级无关

    1)属性:top、left

    2)括号内填写数字可以修改数值

  2. position():元素相对于父级的偏移坐标,没有父级则以文档为参考

    1)属性:top、left

    2)只能获取,不能修改

  3. scrollTop() / scrollLeft():元素被卷去的头部和左侧

    1)配合页面滚动事件:$(window).scroll(function(){...})

    2)页面被卷去的头部:$(document).scrollTop()

    3)返回顶部动画:$("body, html").stop().animate({scrollTop:0})


4.3 jQuery事件

4.3.1 单事件注册

  1. $("element").事件动作(fn(){...}):每次只能绑定一个事件

4.3.2 事件处理: on()

  1. 可以绑定多个事件处理程序

    1)语法:$("element").on(events, [selector], fn)

    2)若多个事件处理方法相同可合并写

  2. 可以实现事件委托/委派

    1)定义:把原来加在子元素身上的绑定事件绑在父元素身上

    2)注意:旧方法bind()、live()、delegate()已经被on()替代

  3. 给未来动态创建的元素绑定事件

    1)绑定尚未创建的子元素:$("ol").on("click", "li",fn{...} )

    2)创建子元素:var li = $("<li>我是后来创建的</li>")

    3)添加子元素:$("ol").append(li)

    4)注意:此时$("ol li").click()是无效的,无法给动态创建的元素添加事件

4.3.3 单次触发: one()

  1. $("element").one(events,[selector],fn):只能触发一次事件

4.3.4 事件解绑: off()

  1. 解绑所有事件:$("element").off()

  2. 解绑指定事件:$("element").off(events)

  3. 解除事件委托:$("element").off(events, [selector])

4.3.5 自动触发: trigger()

  1. $("element").事件():默认方法

  2. $("element").trigger("事件"):触发元素的默认行为

  3. $("element").triggerHandler("事件"):不会触发元素的默认行为,例:表单获得焦点后会有光标闪烁,可以用此方法取消光标闪烁

4.3.6 事件对象: event

  1. $("element").on( events,[selector],fn(event){...}):使用方法与原生JS相同

4.3.7 对象拷贝: extend

  1. 语法:.extend([deep],target,object1,[objectN])

  2. 参数:

    1)deep:可选,默认false浅拷贝,true深拷贝

    • 浅拷贝:把原来对象里面的复杂数据类型地址拷贝给目标对象,修改目标对象也会同时修改原对象
    • 深拷贝:把里面的数据完全复制一份给目标对象,如果里面有不冲突的属性会合并到一起

    2)target:要拷贝的目标对象

    3)object1:待拷贝到第一个对象的对象


4.4 jQuery插件

  1. 网站:

    1)jQuery插件库:www.jq22.com

    2)jQuery之家:www.htmleaf.com

  2. 瀑布流插件:http://www.htmleaf.com/jQuery/pubuliuchajian

  3. 图片懒加载:https://www.jq22.com/jquery-info11629

    1)作用:页面滑动到可视区域再显示图片

    2)注意:此插件需要写到DOM元素的最后面

  4. 全屏滚动:github.com/alvarotrigo/fullPage.js

  5. Bootstrap插件:https://v3.bootcss.com/javascript/


 

Server

第1章 Ajax

1.1 Ajax基础知识

1.1.1 URL

  1. 定义:统一资源定位符(Uniform Resource Locator),互联网上每个文件都有唯一的URL

  2. 语法:protocol: // host [:port] / path / [?query] #fragment

    1)protocol:通信协议,如http、https、maito等

    2)host:主机(域名)

    3)port:端口号,可选,省略时使用方案默认端口,如http默认端口为80

    4)path:路径,表示主机上的一个目录或文件地址

    5)query:参数,以键值对的形式通过&符号分隔开来

    6)fragment:片段,#后面内容常见于链接锚点

1.1.2 客户端与服务器

  1. 客户端与服务器通信(三次握手)

    1)请求:客户端请求服务器。打开浏览器输入网址,向服务器发起资源请求

    2)处理:服务器处理请求。服务器收到客户端的资源请求;服务器内部处理请求,找到相应资源

    3)响应:服务器响应客户端。服务器把找到的资源发送给客户端

  2. Chrome开发者工具分析通信过程

    1)Ctrl+Shift+I:开发者工具面板

    2)Network网络,Doc标签,刷新页面

  3. 网页中请求数据

    1)XMLHttpRequest对象:简称XHR,是浏览器提供的JS成员,通过它可以请求服务器上的数据资源

    2)语法:var xhrObj = new XMLHttpRequest()

    3)get请求:获取服务器资源,根据URL地址从服务器获取HTML、CSS、JS、图片、数据资源等

    4)post请求:向服务器提交数据,提交登录信息、注册信息、用户信息等

1.1.3 Ajax简介

  1. 全称:Asynchronous Javascript And XML(异步JS和XML)

  2. 定义:在网页中利用XMLHttpRequest对象和服务器进行数据交互的方式

  3. 应用场景

    1)用户注册:动态监测用户名是否被占用

    2)搜索提示:输入关键字,动态加载搜索提示列表

    3)分页显示:点击页码值,动态刷新表格中的数据

    4)数据操作:增删改查,进行数据交互

1.1.4 数据接口

  1. 定义:使用Ajax请求数据时,被请求的URL地址称为接口,每个接口必须有【请求方式】
  2. 测试工具:PostMan

1.2 HTTP协议

1.2.1 HTTP协议简介

  1. 通信协议(Communication Protocol):通信的双方完成通信所必须遵守的规则和约定

  2. 通信协议三要素:

    1)通信的主体:服务器、客户端浏览器

    2)通信的内容:数据文本

    3)通信的方式:响应

  3. 超文本传输协议(HyperText Transfer Protocol,HTTP 协议) :网页内容传输协议

    1)规定了客户端与服务器之间进行网页内容传输时,所必须遵守的传输格式

    2)采用【请求/响应】的交互模型

    3)客户端:以HTTP协议要求的格式把数据【提交】到服务器

    4)服务器:以HTTP协议要求的格式把内容【响应】给客户端

1.2.2 HTTP请求

  • HTTP 请求:客户端发起的请求
  • HTTP 请求消息(请求报文):客户端发送到服务器的消息

HTTP请求消息结构

  1. 请求行(request line)

    1)由 请求方式、URL 和 HTTP 协议版本 3 个部分组成,使用空格隔开

    2)例:POST /api/post HTTP/1.1

  2. 请求头部(header):描述客户端的基本信息并告知服务器

    1)Host:要请求的服务器域名

    2)Connection:客户端与服务器的连接方式(close 或 keepalive)

    3)Content-Length:描述请求体的大小

    4)Accept:客户端可识别的响应内容类型列

    5)User-Agent:产生请求的浏览器类型

    6)Content-Type:发送到服务器的数据类型

    7)Accept-Encoding:客户端可接收的内容压缩编码形式

    8)Accept-Language:用户期望获得的自然语言的优先顺序

  3. 空行:

    1)最后一个请求头字段的后面是一个空行,通知服务器请求头部至此结束

    2)请求消息中的空行,用来分隔请求头部与请求体

  4. 请求体:

    1)存放通过 POST 方式提交到服务器的数据

    2)注意:只有 POST 请求才有请求体,GET 请求没有请求体

1.2.3 HTTP响应

HTTP响应消息(响应报文):服务器响应给客户端的消息内容

HTTP响应

  1. 状态行

    1)由 HTTP 协议版本、状态码、状态码的描述文本 3 个部分组成,用空格隔开

    2)例:HTTP/1.1 200 OK

  2. 响应头部:用来描述服务器的基本信息,由多行【键/值】组成,每行的键和值之间用英文的冒号分隔

  3. 空行:

    1)最后一个响应头部字段结束之后,会跟一个空行,用来通知客户端响应头部至此结束

    2)响应消息中的空行,用来分隔响应头部与响应体

  4. 响应体:存放服务器响应给客户端的资源内容

1.2.4 HTTP请求方法

用来表明要对服务器上的资源执行的操作,常用GET、POST

  1. GET:(查询)发送请求来获得服务器上的资源,请求体中不会包含请求数据,请求数据放在协议头中
  2. POST:(新增)向服务器提交资源(例如提交表单或上传文件),数据被包含在请求体中提交给服务器
  3. PUT:(修改)向服务器提交资源,并使用提交的新资源,替换掉服务器对应的旧资源
  4. DELETE:(删除)请求服务器删除指定的资源
  5. HEAD:请求一个与 GET 请求的响应相同的响应,但没有响应体
  6. OPTIONS:获取http服务器支持的http请求方法,允许客户端查看服务器的性能,比如ajax跨域时的预检等
  7. CONNECT:建立一个到由目标资源标识的服务器的隧道
  8. TRACE:沿着到目标资源的路径执行一个消息环回测试,主要用于测试或诊断
  9. PATCH:是对 PUT 方法的补充,用来对已知资源进行局部更新

1.2.5 HTTP响应状态代码

HTTP Status Code,属于 HTTP 协议的一部分,用来标识响应的状态,随着响应消息一起被发送至客户端浏览器。由3个十进制数字组成,第1个十进制数字定义了状态码的类型,后2个数字用来对状态码进行细分。

  1. 1**:信息,服务器收到请求,需要请求者继续执行操作(少见)

  2. 2**:成功,操作被成功接收并处理

    1)200:OK,请求成功。一般用于 GET 与 POST 请求

    2)201:Created,已创建。成功请求并创建了新的资源,通常用于 POST 或 PUT 请求

  3. 3**:重定向,需要进一步的操作以完成请求

    1)301:Moved Permanently,永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替

    2)302:Found,临时移动。与301类似,但资源只是临时被移动。客户端应继续使用原有URI

    3)304:Not Modified,未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源(响应消息中不包含响应体),客户端通常会缓存访问过的资源

  4. 4**:客户端错误,请求包含语法错误或无法完成请求

    1)400:Bad Request,语义有误,当前请求无法被服务器理解,除非进行修改,否则客户端不应该重复提交这个请求;请求参数有误

    2)401:Unauthorized,当前请求需要用户验证

    3)403:Forbidden,服务器已经理解请求,但是拒绝执行它

    4)404:Not Found,服务器无法根据客户端的请求找到资源(网页)

    5)408:Request Timeout,请求超时。服务器等待客户端发送的请求时间过长超时

  5. 5**:服务器错误,服务器在处理请求的过程中发生了错误

    1)500:Internal Server Error,服务器内部错误,无法完成请求

    2)501:Not Implemented,服务器不支持该请求方法,无法完成请求。只有 GET 和 HEAD 请求方法是要求每个服务器必须支持的,其它请求方法在不支持的服务器上会返回501

    3)503:Service Unavailable,由于超载或系统维护,服务器暂时的无法处理客户端的请求


1.3 XMLHttpRequest

XMLHttpRequest 是浏览器提供的 Javascript 对象,通过它可以请求服务器上的数据资源,Ajax就是基于XHR对象封装出来的。

1.3.1 GET请求

1.3.1.1 一般步骤
  1. 创建 xhr 对象:var xhr = new XMLHttpRequest()

  2. 调用 xhr.open() 函数:指定请求方式和URL地址,xhr.open('GET', url)

  3. 调用 xhr.send() 函数:发起ajax请求,xhr.send()

  4. 监听 xhr.onreadystatechange 事件

    1)xhr对象的请求状态:readyState

    • 0:UNSENT,xhr对象已创建,但未调用open方法
    • 1:OPENED,open方法已调用
    • 2:HEADERS_RECEIVED,send方法已调用,响应头已被接收
    • 3:LOADING,数据接收中,response属性中已包含部分数据
    • 4:DONE,Ajax请求完成,数据传输已经彻底完成或失败

    2)服务器的响应状态:status,这里的status和数据中的status不是一个东西

    3)返回结果:xhr.responseText

1.3.1.2 携带参数
  1. 查询字符串:在 URL 的末尾加上用于向服务器发送信息的字符串(变量)

    1)将英文的?放在URL的末尾,然后再加上参数=值

    2)想加上多个参数的话,使用 & 符号进行分隔

    3)例:http://www.liulongbin.top:3006/api/getbooks?id=1&bookname=西游记

  2. 本质上就是将查询字符串追加到url地址后面

  3. URL编码与解码:URL中不允许出现中文字符,故需要用英文字符去表示非英文字符

    1)encodeURI() :编码的函数

    2)decodeURI() :解码的函数

    3)规律:每1个中文字符对应3个百分号字符


1.3.2 POST请求

  1. 创建 xhr 对象:var xhr = new XMLHttpRequest()

  2. 调用 xhr.open() :指定请求方式和URL地址,xhr.open('GET', url)

  3. 设置 Content-Type 属性(固定写法):xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')

  4. 调用 xhr.send(),将数据以查询字符串的形式提交给服务器

  5. 监听 xhr.onreadystatechange 事件

    1)xhr对象的请求状态:readyState

    2)服务器的响应状态:status,这里的status和数据中的status不是一个东西

    3)返回结果:xhr.responseText,JSON.parse()可以转为对象


1.3.3 封装Ajax

  1. 效果:myajax({method, url, data : {...}, success: function(){..})

  2. 定义转换函数:把data对象转为查询字符串

  3. 创建XHR对象

  4. 发起请求:

    1)发起GET请求

    2)发起POST请求

  5. 监听 xhr.onreadystatechange 事件:用JSON.parse()转为对象


1.3.4 新版XHR

旧版XHR的缺点:只支持文本数据的传输,无法用来读取和上传文件;传送和接收数据时,没有进度信息,只能提示有没有完成

  1. 设置 HTTP 请求的时限:

  2. 用 FormData 对象管理表单数据:

    1)添加数据:这里添加的数据都被加到返回的data对象中了

    2)获取表单数据

  3. 文件上传

  4. 获得数据传输的进度信息

    1)监听上传进度的事件:xhr.upload.onprogress = function(e) {...}

    • e.lengthComputable:布尔值,表示当前上传的资源是否具有可计算的长度
    • e.loaded:已传输的字节
    • e.total:需传输的总字节
    • 计算进度:var percentComplete = Math.ceil((e.loaded / e.total) * 100)

    2)监听上传完成的事件:xhr.upload.onload


1.4 数据交换格式

服务器端与客户端之间进行数据传输与交换的格式,主要包括 XML 和 JSON

1.4.1 XML

  1. 定义:EXtensible Markup Language,可扩展标记语言

  2. 与HTML的区别:

    1)HTML 被设计用来描述网页上的内容,是网页内容的载体

    2)XML 被设计用来传输和存储数据,是数据的载体

  3. 缺点:

    1)格式臃肿,和数据无关的代码多、体积大、传输效率低

    2)在 Javascript 中解析 XML 比较麻烦

1.4.2 JSON

  1. 定义:JavaScript Object Notation,JavaScript 对象表示法,本质是【字符串】

  2. 特点:轻量级的文本数据交换格式,比 XML 更小、更快、更易解析

  3. 结构:

    1)对象结构{key: value,}:key必须是使用英文的双引号包裹的字符串;value 可以是数字、字符串、布尔值、null、数组、对象

    2)数组结构[]:数字、字符串、布尔值、null、数组、对象

  4. 规则:

    1)属性名必须使用双引号包裹

    2)字符串类型的值必须使用双引号包裹,不允许使用单引号表示字符串

    3)JSON 中不能写注释

    4)JSON 的最外层必须是对象或数组格式

    5)不能使用 undefined 或函数作为 JSON 的值

  5. 区别:

    1)JS对象:var obj = {a: 'Hello', b: 'World'},字符串用单引号,外部无引号

    2)JSON字符串:var json = '{"a": "Hello", "b": "World"}',字符串用双引号,外部单引号

  6. 转换:

    1)JS对象转JSON:JSON.stringify(obj),JSON 序列化

    2)JSON转JS对象:JSON.parse(JSON),JSON 反序列化


1.5 jQuery中的Ajax

  1. 定义:浏览器中提供的XMLHttpRequest用法复杂,jQuery对其进行了封装,降低了Ajax的使用难度
  2. 查看响应数据:F12-网络-XHR-响应

1.5.1 Ajax方法

1.5.1.1 GET请求
  1. $.get(url,[data],[callbkack]):从服务器获取数据

  2. 参数:

    1)url:string,资源地址

    2)data:object,请求资源期间要携带的参数

    3)callback:function,请求成功时的回调函数,可通过事件对象e返回数据

1.5.1.2 POST请求
  1. $.post(url,[data],[callbkack]):将数据提交到服务器

1.5.1.3 Ajax请求
  1. $.ajax({type/method, url, data, success: function(res){...}):get和post请求均可

  2. 参数:

    1)type:string,请求的方式,GET、POST

    2)url:string,资源地址

    3)data:object,请求要携带的数据

    4)success:function(res) {...},请求成功后的回调函数

1.5.1.4 服务器响应机制
  1. 如果成功:执行success回调函数

  2. 如果失败:执行error回调函数

  3. 无论成功或失败:执行complete函数

  4. 服务器返回数据:res.responseJSON

1.5.1.5 案例:图书管理
  1. 接口文档:

    1)请求根路径:http://www.liulongbin.top:3006

    2)接口URL:/api/getbooks,调用方式:GET

    3)接口URL:/api/addbook,调用方式:POST

    4)接口URL:/api/delbook,调用方式:GET

  2. 完整代码

1.5.1.6 案例:聊天机器人
  1. API接口:

    1)新接口1:http://www.liulongbin.top:3006/api/robot

    2)新接口2:http://www.liulongbin.top:3006/api/synthesize

  2. 通过<audio>播放语音:

    1)原理:只要为 audio 指定了新的 src 属性,而且指定了 autoplay,语音就会自动播放

    2)html:<audio src="" id="voice" autoplay style="display: none"></audio>

    3)JS:$('#voice').attr('src', res.voiceUrl)

  3. 使用回车键发送消息:给文本输入框绑定keyup事件,当e.keyCode===13时触发点击按钮事件

  4. 案例完整代码


1.5.2 文件上传

  1. 定义HTML结构

  2. 验证是否选择了文件

  3. 向FormData中追加文件

  4. ajax发起上传文件的请求

    1)contentType: false:不修改 Content-Type 属性,使用 FormData 默认的 Content-Type 值

    2)processData: false:不对 FormData 中的数据进行 url 编码,而是将 FormData 数据原样发送到服务器

  5. 实现loading效果

    1)ajaxStart(callback):callback 中定义 loading 效果

    2)ajaxStop(callback):callback 中定义 finish 效果

    3)注意:$(document).ajaxStart() 函数会监听当前文档内所有的 Ajax 请求


1.5.3 ajaxPrefilter

  1. 作用:每次调用get/post/ajax的时候会先调用此函数,可以对ajax进行配置

  2. 引入:如果是在外部文件定义的,需要引入该js文件,位置在调用ajax函数之前

  3. oprions.url:设置地址前缀,不用每次在ajax中重复输入一长串地址了

  4. options.header:设置请求头,如果需要的话

  5. options.complete:设置服务器返回结果后的complete回调函数


1.6 Form表单

表单主要负责数据采集功能,<form>就是用于采集用户输入的信息,通过提交操作提交到服务器。三要素:表单标签、表单域、表单按钮。

1.6.1 表单属性

  1. action:当提交表单时,向何处发送表单数据,提交后页面自动跳转到该URL地址

    1)值:URL地址

    2)注意:如果未指定URL地址,默认提交到当前页面地址

  2. method:以何种方式把表单数据提交到action URL

    1)GET:默认,通过URL地址(字符串)的形式,把表单数据提交到action URL

    2)POST:常用,可提交隐私/大量/复杂/文件上传数据,不显示在URL中

  3. enctype:在发送表单数据之前如何对其进行编码

    1)application/x-www-form-urlencoded:默认,发送前编码所有字符

    2)multipart/form-data:不对字符编码,使用包含文件上传控件的表单时,必须使用该值

    3)text/plain:空格转换为“+”加号,但不对特殊字符编码(很少用)

  4. target:在何处打开action URL

    1)_self:默认,在相同框架下打开action URL

    2)_blank:在新窗口中打开

    3)_parent:在父框架集中打开(很少用)

    4)_top:在整个窗口中打开(很少用)

    5)framename:在指定框架中打开(很少用)

1.6.2 同步提交

  1. 定义:点击submit按钮触发表单提交操作,使页面跳转到action URL的行为
  2. 缺点:整个页面会发生跳转到 action URL 所指向的地址,用户体验很差;页面之前的状态和数据会丢失
  3. 解决方案:表单只负责采集数据,Ajax 负责将数据提交到服务器

1.6.3 Ajax提交数据

  1. 监听表单提交事件

    1)方法1:$('#form1').submit(function(e) {...}

    2)方法2:$('#form1').on('submit', function(e) {...}

  2. 阻止表单默认提交行为:event.preventDefault()

  3. 获取表单中的数据:$(selector).serialize()

    1)作用:可以一次性获取到表单中的所有的数据

    2)注意:必须为每个表单元素添加 name 属性才能使用该函数

1.6.4 案例:评论列表

  1. 使用bootstrap搭建


1.7 Axios

Axios是专注于网络数据请求的库,比XHR更简单易用,比jQuery更轻量化。

  1. GET请求:axios.get('url', {params: {/*参数*/}}).then(callback)

  2. POST请求:axios.post('url', {/*参数*/}).then(callback)

  3. 直接用Axios发起请求

    1)语法

    2)GET请求

    3)POST请求


1.8 跨域与JSONP

1.8.1 同源策略与跨域

1.8.1.1 同源
  1. 定义:如果两个页面的【协议】【域名】【端口】都相同,则两个页面具有相同的源

  2. 注意:如果在域名后面没指定端口,默认是80端口

  3. 同源策略:Same origin policy,是浏览器提供的一个安全功能

    1)作用:同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制

    2)无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB

    3)无法接触非同源网页的 DOM

    4)无法向非同源地址发送 Ajax 请求

1.8.1.2 跨域
  1. 定义:同源指的是两个 URL 的协议、域名、端口一致,反之则是跨域

  2. 引子:浏览器允许发起跨域请求,但是跨域请求回来的数据,会被浏览器拦截,无法被页面获取到

  3. JSONP:出现的早,兼容性好(兼容低版本IE)

    1)是前端程序员为了解决跨域问题,被迫想出来的一种临时解决方案

    2)缺点:只支持 GET 请求,不支持 POST 请求

  4. CORS:支持 GET 和 POST 请求

    1)出现的较晚,是W3C 标准,属于跨域 Ajax 请求的根本解决方案

    2)缺点:不兼容某些低版本的浏览器


1.8.2 JSONP

JSON with Padding,是 JSON 的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。JSONP 和 Ajax 之间没有任何关系,不能把 JSONP 请求数据的方式叫做 Ajax,因为 JSONP 没有用到 XMLHttpRequest。

1.8.2.1 JSONP实现原理
  1. <script>标签不受浏览器同源策略的影响,可以通过 src 属性请求非同源的 js 脚本

  2. 通过<script>标签的 src 属性,请求跨域的数据接口,并通过函数调用的形式,接收跨域接口响应回来的数据

  3. 通过查询字符串的形式进行函数调用:实际API中会在url后面加 ?jsonp 查询字符串

  4. 案例:实现简单的JSONP数据请求

1.8.2.2 jQuery发起JSONP请求
  1. $.ajax({url, dataType, jsonp, jsonpCallback, success: function(){}})

    1)dataType: 'jsonp',必须指定

    2)jsonp: 'callback',发送到服务端的参数名称,默认值是callback

    3)jsonpCallback: 'abc',自定义的回调函数名称,如果不指定,会随机生成 callback=jQueryxxx

  2. 实现过程

    1)原理:动态创建和移除<script> 标签

    2)在发起 JSONP 请求的时候,动态向 <header> 中 append 一个 <script> 标签

    3)在 JSONP 请求成功以后,动态从 <header> 中移除刚才 append 进去的 <script> 标签


1.8.3 防抖 debounce

  1. 定义:当事件被触发后延迟 n 秒后再执行回调,如果在这 n 秒内事件又被触发则重新计时

  2. 应用:用户连续输入一串字符时,通过防抖策略,只在输入完后才执行查询请求,有效减少请求次数,节约请求资源

  3. 缓存:将用户曾经搜索过的结果缓存到对象中,每次搜索先去对象中查找,如果没有的话再请求服务器

  4. 案例:淘宝搜索框-防抖与缓存


1.8.4 节流 throttle

  1. 定义:可以减少一段时间内事件的触发频率

  2. 应用:

    1)鼠标连续不断地触发某事件(如点击),只在单位时间内只触发一次

    2)懒加载时要监听计算滚动条的位置,但不必每次滑动都触发,可以降低计算的频率,而不必去浪费 CPU 资源

  3. 节流阀

    1)节流阀为空,表示可以执行下次操作;不为空,表示不能执行下次操作

    2)当前操作执行完,必须将节流阀重置为空,表示可以执行下次操作了

    3)每次执行操作前,必须先判断节流阀是否为空


第2章 Git

2.1 Git基本概念

2.1.1 控制系统

2.1.1.1 本地版本控制系统
  1. 单机运行,不支持多人协作开发
  2. 版本数据库故障后,所有历史更新记录会丢失
2.1.2 集中化的版本控制系统

典型代表:SVN

  1. 特点:

    1)基于服务器、客户端的运行模式

    2)服务器保存文件的所有更新记录

    3)客户端只保留最新的文件版本

  2. 优点:联网运行,支持多人协作开发

  3. 缺点:

    1)不支持离线提交版本更新

    2)中心服务器崩溃后,所有人无法正常工作

    3)版本数据库故障后,所有历史更新记录会丢失

2.1.3 分布式版本控制系统

典型代表:Git

  1. 特点:

    1)基于服务器、客户端的运行模式

    2)服务器保存文件的所有更新版本

    3)客户端是服务器的完整备份,并不是只保留文件的最新版本

  2. 优点:

    1)联网运行,支持多人协作开发

    2)客户端断网后支持离线本地提交版本更新

    3)服务器故障或损坏后,可使用任何一个客户端的备份进行恢复


2.1.2 Git基础概念

Git是一个开源的分布式版本控制系统,是目前世界上最先进、最流行的版本控制系统。可以快速高效地处理从很小到非常大的项目版本管理。

  1. 特点:项目越大越复杂,协同开发者越多,越能体现出 Git 的高性能和高可用性

  2. 直接记录快照,而非差异比较:

    1)SVN的差异比较:存储的是一组基本文件和每个文件随时间逐步累积的差异

    • 优点:节省磁盘空间
    • 缺点:耗时、效率低;在每次切换版本的时候,都需要在基本文件的基础上,应用每个差异,从而生成目标版本对应的文件

    2)Git 的记录快照:在原有文件版本的基础上重新生成一份新的文件,类似于备份。为了效率,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件

    • 优点:版本切换时非常快,因为每个版本都是完整的文件快照,切换版本时直接恢复目标版本的快照即可
    • 缺点:占用磁盘空间较大
    • 特点:空间换时间
  3. 近乎所有操作都是本地执行:

    1)断网后依旧可以在本地对项目进行版本管理

    2)联网后,把本地修改的记录同步到云端服务器即可

  4. 三个区域:

    1)工作区:处理工作的区域

    2)暂存区:已完成的工作的临时存放区域,等待被提交

    3)Git 仓库:最终的存放区域

  5. 四种状态:

    1)已修改(Modified):表示修改了文件,但还没将修改的结果放到暂存区;工作区的文件被修改了,但还没有放到暂存区,就是已修改状态

    2)已暂存(Staged):表示对已修改文件的当前版本做了标记,使之包含在下次提交的列表中;如果文件已修改并放入暂存区,就属于已暂存状态

    3)已提交(Committed):表示文件已经安全地保存在本地的 Git 仓库中;如果 Git 仓库中保存着特定版本的文件,就属于已提交状态

    4)未跟踪(Untracked):不被 Git 所管理的文件


2.2 安装并配置Git

  1. 下载地址:https://git-scm.com/downloads

  2. 配置用户信息:

  3. 检查配置信息:

    1)全局配置文件

    2)查看所有全局配置项

    3)查看制定的全局配置项

  4. 获取帮助信息:

    1)查看帮助

    2)打开config帮助手册

    3)获取git config命令的快速参考


2.3 Git操作

2.3.1 常用命令

git工作流

2.3.1.1 获取仓库
  1. 将尚未进行版本控制的本地目录转换为 Git 仓库(形式:.git文件夹)

  2. 从其它服务器克隆一个已存在的 Git 仓库

2.3.1.2 检查状态
  1. 命令:

  2. 状态:

    • M:已修改
    • A:新添加到暂存区
    • D:已删除
    • R:重命名
    • C:已复制
    • ??:未跟踪
    • !!:已忽略
2.3.1.3 暂存文件
  1. 添加单个文件:

  2. 添加所有新增与修改过的文件

  3. 状态:A,已被跟踪并处于暂存状态(Changes to be committed)

2.3.1.4 取消暂存
  1. 命令:

2.3.1.5 提交更新
  1. 命令:

  2. 状态:nothing to commit, working tree clean

2.3.1.6 跳过暂存区直接提交
  1. 将“工作区 → 暂存区 → Git 仓库”的中间步骤省略,直接“工作区 → Git 仓库”

  2. 命令:


2.3.2 修改文件

git修改文件

2.3.2.1 修改已提交文件
  1. 场景:对已被git跟踪的文件进行修改
  2. 状态:红色M,已跟踪文件的内容发生了变化,但还没有放到暂存区(Changes not staged for commit)
2.3.2.2 暂存已修改文件
  1. 命令:

  2. 状态:绿色M,已修改并放入暂存区(modified)

2.3.2.3 提交已暂存文件
  1. 命令:

  2. 状态:nothing to commit, working tree clean

2.3.2.4 撤销修改

git撤销修改

  1. 命令:

  2. 场景:把对工作区中对应文件的修改,还原成 Git 仓库中所保存的版本

  3. 影响:所有的修改会丢失,且无法恢复!危险性比较高,请慎重操作!

  4. 本质:用 Git 仓库中保存的文件,覆盖工作区中指定的文件


2.3.3 删除文件

  1. 从 Git 仓库和工作区中同时移除对应的文件

  2. 只从 Git 仓库中移除指定的文件,但保留工作区中对应的文件


2.3.4 忽略文件 gitignore

  1. 语法:

    1)以 # 开头的是注释

    2)以 / 结尾的是目录:例:build/,忽略任何目录下名为build的文件夹

    3)以 / 开头防止递归,例:/TODO,只忽略当前目录下的TODO文件,而不忽略subdir/TODO

    4)以 ! 开头表示取反

    5)可用 glob 模式(简化了的正则表达式)进行文件和文件夹的匹配

  2. glob 模式

    1)?:只匹配一个任意字符

    2)*:匹配0个或多个任意字符,例:doc/*.txt,忽略doc/notes.txt,但不忽略`doc/server/arch.txt``

    3)`**:匹配任意中间目录

    • 例:a/**/z 可以匹配 a/za/b/za/b/c/z
    • 例:doc/**/*.pdf,忽略doc/目录及其所有子目录下的.pdf文件

    4)[]:匹配任何一个列在方括号中的字符

    5)[-]:所有在这两个字符范围内的都可以匹配


2.3.5 查看提交历史 git log

  1. 按时间先后顺序列出所有的提交历史,最近的排在最上面

  2. 只展示最新的2条提交历史

  3. 在上一行展示最近2条提交历史的信息

  4. 自定义输出格式

    1)%h:提交的简写哈希值

    2)%an:作者名字

    3)%ar:作者修订日期,按多久以前的方式显示

    4)%s:提交说明


2.3.6 回退到指定的版本

  1. 在上一行展示所有提交历史

  2. 根据指定的提交ID回退到指定版本

  3. 回退到旧版本后查看命令操作历史

  4. 根据指定的提交ID回退到指定版本


2.4 Github

  1. 开源许可协议(Open Source License):限制使用者的使用范围和保护作者的权利

    1)BSD(Berkeley Software Distribution)

    2)Apache Licence 2.0

    3)GPL(GNU General Public License):不允许修改后和衍生的代码做为闭源的商业软件发布和销售,最著名的软件项目是:Linux

    4)LGPL(GNU Lesser General Public License)

    5)MIT:限制最少的协议,只需在修改后的代码或者发行包中包含原作者的许可信息,使用MIT的项目有:jquery、Node.js

  2. 托管平台:以下3个开源项目托管平台,只能托管以Git管理的项目源代码

    1)Github:全球最牛的开源项目托管平台,没有之一

    2)Gitlab:对代码私有性支持较好,因此企业用户较多

    3)Gitee:又叫做码云,是国产的开源项目托管平台。访问速度快、纯中文界面、使用友好

  3. 主要功能:

    1)Star:关注自己喜欢的开源项目

    2)Pull Request:为自己喜欢的开源项目做贡献

    3)Issues:和开源项目的作者讨论 Bug 和提需求

    4)Fork:把喜欢的项目复制一份作为自己的项目进行修改

  4. 访问仓库:

    1)HTTPS:零配置;但是每次访问仓库时,需要重复输入 Github 的账号和密码才能访问成功

    2)SSH:(推荐)需要进行额外的配置;但是配置成功后,每次访问仓库时,不需重复输入 Github 的账号和密码

  5. 关联仓库

    1)本地没有仓库

    2)本地已有仓库

  6. SSH key

    1)作用:实现本地仓库和 Github 之间免登录的加密数据传输

    2)结构:

    • id_rsa:私钥文件,存放于客户端的电脑中
    • id_rsa.pub:公钥文件,需要配置到 Github 中

    3)命令:

    4)配置:将 id_rsa.pub 中的公钥复制到Github的SSH设置中

    5)检测:


2.5 Git分支

git分支

  1. 作用:多人协作开发时,为了防止互相干扰,提高协同开发的体验,建议每个开发者都基于分支进行项目功能的开发
  2. 功能分支:专门用来开发新功能的分支,临时从 master 主分支上分叉出来,当新功能开发且测试完毕后,最终需要合并到 master 主分支上

2.5.1 main主分支

  1. 作用:git默认创建的分支,用来保存和记录整个项目已完成的功能代码
  2. 有时候也叫master分支,需要看github上面的名称
  3. 不允许程序员直接在 master 分支上修改代码,因为这样做的风险太高,容易导致整个项目崩溃

2.5.2 本地分支

  1. 查看分支列表:分支名字前面的 * 号表示当前所处的分支

  2. 创建新分支:基于当前分支创建一个新的分支,分支中的代码和当前分支完全一样

  3. 切换分支:切换到指定的分支上进行开发

  4. 分支的快速创建和切换:创建指定名称的新分支,并立即切换到新分支上

  5. 合并分支:功能分支的代码开发测试完毕之后,将完成后的代码合并到master主分支上

  6. 删除分支:当把功能分支的代码合并到 master 主分支上以后,删除对应的功能分支

  7. 遇到冲突时的分支合并:如果在两个不同的分支中,对同一个文件进行了不同的修改,Git就没法干净的合并它们,需要手动解决冲突

2.5.3 远程分支

  1. 将本地分支推送到远程仓库:

    1)首次推送带-u参数

    2)若远程和本地分支名称一致

  2. 查看远程仓库中所有的分支列表:需要在本地仓库根目录中打开bash

  3. 跟踪分支:从远程仓库中,把远程分支下载到本地仓库中

    1)远程仓库与本地仓库分支名称相同

    2)远程仓库与本地仓库分支名称不同

  4. 拉取远程分支的最新的代码:当前处于哪个分支,就更新该分支的代码

  5. 删除远程分支


第3章 Node.js

3.1 基础知识

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境

  1. 官网:https://nodejs.org/zh-cn/

  2. 作用:可以使 JavaScript 基于Node.js 做后端开发

  3. 版本:

    1)LTS:长期稳定版,适合追求稳定性的企业级项目(推荐)

    2)Current:新特性尝鲜版,适合热衷于尝试新特性的用户,但可能有Bug和漏洞

  4. 区别:Node.js 中无法调用 DOM 和 BOM 等浏览器内置 API,只能调用Node.js的内置API

    环境图解
    浏览器:JavaScript 的前端运行环境JavaScript 的前端运行环境
    Node.js:JavaScript 的后端运行环境JavaScript 的后端运行环境
  5. 工具:

    1)Express:快速构建 Web 应用

    2)Electron:构建跨平台的桌面应用

    3)Restify:快速构建 API 接口项目

  6. 执行命令:node 项目名称.js

  7. nodemon:调试工具,能够监听项目文件的变动,当代码被修改后,nodemon 会自动重启项目

    1)安装:npm i nodemon -g

    2)运行:nodemon 项目名称.js


3.2 内置API

3.2.1 FS模块

fs模块是官方提供的、用来操作文件的模块。

  1. 导入:

  2. fs.readFile(path[,options],callback):用来读取指定文件中的内容

    1)参数:

    • path:文件的路径
    • options:可选,以什么编码格式来读取文件,如 utf8
    • callback:文件读取完成后,通过回调函数拿到读取的结果

    2)回调函数:function(err, result)

    • err:如果为 null,表示读取成功;如果是ture,可用 err.message 显示错误信息
    • result:读取结果
  3. fs.writeFile(file,data[,options],callback):用来向指定的文件中写入内容

    1)参数:

    • path:文件的路径
    • data:要写入的内容
    • options:可选,以什么编码格式来写入文件,默认 utf8
    • callback:文件写入完成后的回调函数

    2)回调函数:function(err)

    • err:如果为 null,表示写入成功;如果是 ture,可用 err.message 显示错误信息

    3)fs.writeFile() 方法只能用来创建文件,不能用来创建路径

    4)重复调用 fs.writeFile() 写入同一个文件,新写入的内容会覆盖之前的旧内容

  4. 路径动态拼接的问题

    1)问题:如果提供的操作路径是以 ./../ 开头的相对路径时,很容易出现路径动态拼接错误的问题

    2)解决:__dirname,表示当前文件所处目录,直接提供完整的路径

    3)注意:路径拼接用 path.join() 方法进行处理,不要直接使用 + 进行字符串的拼接


3.2.2 Path模块

path模块是官方提供的、用来处理路径的模块。

  1. 导入:

  2. path.join([...paths]):用来将多个路径片段拼接成一个完整的路径字符串

    1)...paths:可选,路径片段的序列

    2)注意:../ 会抵消前面的路径

  3. path.basename(path[,ext]):用来从路径字符串中将文件名解析出来

    1)path:路径字符串

    2)ext:可选,件扩展名

  4. path.extname(path):获取路径中的扩展名部分

    1)path:路径字符串

  5. 案例:时钟,将html文件中的css和js分拆出单独的文件


3.2.3 Http模块

Http模块是官方提供的、用来创建 web 服务器的模块。

  1. req 请求对象:包含了与客户端相关的数据和属性

    1)req.rul:客户端请求的URL地址

    2)req.method:客户端的请求类型

  2. res 响应对象:包含了与服务器相关的数据和属性

    1)res.end():向客户端发送指定内容,并结束本次请求的处理过程

    2)解决中文乱码问题:res.setHeader('Content-Type', 'text/html; charset=utf-8')

  3. 导入:

  4. 创建基本服务器:

    1)创建 web 服务器实例:const serve = http.createServer()

    2)为服务器实例绑定 request 事件:server.on('request', function(req,res){...})

    3)启动服务器 listen():server.listen(8080,function (){...})

  5. 案例:根据不同的 url 响应不同的 html 内容

    1)获取请求的 url 地址:const url = req.url

    2)设置默认的响应内容为 404 Not found:let content = '<h1>404 Not found!</h1>'

    3)判断用户请求的是否为 / 或 /index.html 首页

    4)判断用户请求的是否为 /about.html 关于页面

    5)设置 Content-Type 响应头,防止中文乱码:res.setHeader('Content-Type', 'text/html; charset=utf-8')

    6)使用 res.end() 把内容响应给客户端:res.end(content)

  6. 案例:创建clock时钟服务器

    1)将资源的请求 url 地址映射为文件的存放路径

    2)读取文件内容并响应给客户端


3.3 模块化

解决一个复杂问题时,自顶向下逐层把系统划分成若干模块的过程。对于整个系统来说,模块是可组合、分解和更换的单元。

3.3.1 模块的加载机制

  1. 模块在第一次加载后会被缓存,多次调用 require() 不会导致模块的代码被执行多次。

  2. 内置模块的加载机制:

    1)内置模块的加载优先级最高

    2)require('fs') 始终返回内置的fs模块,即使在node_modules目录下有名字相同的包也叫做fs

  3. 自定义模块的加载机制:

    1)必须指定以 ./ 或 ../ 开头的路径标识符,否则会当作内置模块或第三方模块进行加载

    2)如果省略文件扩展名,按以下顺序加载:

    • 按照确切的文件名进行加载
    • 补全 .js 扩展名进行加载
    • 补全 .json 扩展名进行加载
    • 补全 .node 扩展名进行加载
  4. 第三方模块的加载机制

    1)如果传递给 require() 的模块标识符不是一个内置模块,也没有以 ./../ 开头,则为第三方模块

    2)加载顺序:假设在 'C:\Users\itheima\project\foo.js' 文件里调用了 require('tools')

    • 当前目录的/node_modules 文件夹,找不到则移动到再上一层父目录
    • C:\Users\itheima\project\node_modules\tools
    • C:\Users\itheima\node_modules\tools
    • C:\Users\node_modules\tools
    • C:\node_modules\tools
  5. 目录作为模块:

    1)在被加载的目录下查找 package.json 文件,寻找 main 属性,作为 require() 加载入口

    2)如果目录没有 package.json 文件,或 main 入口不存在或无法解析, Node.js 将会试图加载目录下的 index.js 文件

    3)如果以上两步均失败,会报错


3.3.2 Node.js中的模块化

  1. 模块的分类:

    1)内置模块:由 Node.js 官方提供的,例如 fs、path、http 等

    2)自定义模块:用户创建的每个 .js 文件,都是自定义模块

    3)第三方模块:由第三方开发出来的模块,使用前需要先下载

  2. 加载模块:require()

  3. 模块作用域:在自定义模块中定义的变量、方法等成员,只能在当前模块内被访问

  4. 向外共享模块作用域中的成员:

    向外共享模块作用域中的成员

    1)module 对象:在每个 .js 自定义模块中都有,里面存储了和当前模块有关信息

    2)module.exports 对象:

    • 作用:可将模块内的成员共享出去,供外界使用
    • 外界用 require() 方法导入自定义模块时,得到的就是 module.exports 所指向的对象
    • 在自定义模块中,默认 module.exports = {}

    3)exports 对象:为了简化书写,exports 和 module.exports 指向同一个对象,但冲突时以后者为准

    4)注意:require() 模块时,得到的永远是 module.exports 指向的对象;为了防止混乱,不要在同一个模块中同时使用 exports 和 module.exports

  5. 模块化规范:遵循 CommonJS 模块化规范,规定了模块的特性和各模块之间如何相互依赖

    1)每个模块内部,module 变量代表当前模块

    2)module 变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口

    3)加载某个模块,其实是加载该模块的 module.exports 属性,require() 方法用于加载模块


3.4 npm与包

3.4.0 npm常用包

  1. moment:格式化时间

  2. i5ting_toc:可以把 md 文档转为 html 页面的小工具


3.4.1 npm简介

  1. 定义:Node.js 中的第三方模块又叫做包

  2. 全球最大的包共享平台:npm,Inc

    1)搜索:https://www.npmjs.com

    2)下载源:https://registry.npmjs.org

    3)国内镜像:https://registry.npm.taobao.org

  3. npm 包管理工具:Node Package Manager(随 Node.js 一起安装了)

  4. 包的语义化版本规范:

    1)以“点分十进制”形式进行定义,总共有三位数字,如:2.24.0

    2)第1位数字:大版本,第2位数字:功能版本,第3位数字:Bug修复版本

    3)版本号提升的规则:只要前面的版本号增长了,则后面的版本号归零

  5. 规范的包结构

    1)包必须以单独的目录而存在

    2)包的顶级目录下要必须包含 package.json 这个包管理配置文件

    3)package.json 中必须包含 nameversionmain 这三个属性,分别代表包的名字、版本号、包的入口


3.4.3 包的分类

  1. 项目包:被安装到项目的 node_modules 目录中的包

    1)开发依赖包:被记录到 devDependencies 节点中的包,只在开发期间会用到

    2)核心依赖包:被记录到 dependencies 节点中的包,在开发期间和项目上线之后都会用到

  2. 全局包:全局包会被安装到 C:\Users\用户目录\AppData\Roaming\npm\node_modules 目录下

    1)安装命令

    2)卸载命令

    3)只有工具性质的包才有全局安装的必要性,它们提供了好用的终端命令;判断某个包是否需要全局安装后才能使用,可以参考官方提供的使用说明即可


3.4.3 npm管理

  1. 快速创建项目:项目文件夹名不能有中文,路径可以有中文

  2. 安装包:不同类型包的安装方法

  3. 文件结构:

    1)node_modules 文件夹:存放所有已安装到项目中的包

    2)package-lock.json 配置文件:记录 node_modules 目录下的每一个包的下载信息,例如包的名字、版本号、下载地址等

  4. 包管理配置文件:package.json

    1)引子:多人协作时,第三方包的体积过大,不方便团队成员之间共享项目源代码,需要删除node_modules文件夹

    2)作用:记录项目中安装了哪些包,从而方便剔除 node_modules 目录之后,在团队成员之间共享项目的源代码

    3)内容:

    • 项目的名称、版本号、描述等
    • 项目中都用到了哪些包
    • 哪些包只在开发期间会用到
    • 那些包在开发和部署时都需要用到

    4)注意:开发时一定要把 node_modules 文件夹,添加到 .gitignore 忽略文件中

    5)dependencies 节点:记录使用 npm 命令安装了哪些包

    6)devDependencies 节点:只在项目开发阶段会用到的包,在项目上线之后不会用到

  5. 一次性安装所有包:npm 先读取package.json中的dependencies节点,一次性下载到项目中

  6. 卸载包:执行成功后,会把卸载的包自动从 package.json 的 dependencies 中移除掉

    1)卸载项目包:

  7. 切换镜像:

    1)查看镜像源

    2)切换镜像源

    3)nrm 小工具:可以代替传统方法查看和切换镜像源

    • 安装nrm
    • 查看所有可用镜像源
    • 切换淘宝镜像源

3.4.4 开发自己的包

3.4.4.1 定义包
  1. 包管理配置文件:package.json

    1)必须:name、version、main

    2)可选:description、keywords、license

  2. 包的入口文件:index.js

  3. 包的说明文档:README.md

  4. src文件夹:定义函数

    1)dateFormat.js

    2)htmlEscape.js

3.4.4.2 发布包
  1. 注册登录:https://www.npmjs.com

  2. 将下包的服务器地址切换为 npm 的官方服务器

  3. 登录:npm login

  4. 切换到包的根目录并发布:npm publish

3.4.4.3 删除包
  1. 只能删除 72 小时以内发布的包,删除后在 24 小时内不允许重复发布


3.5 Express

Express是一个基于 Node.js 平台,快速、开放、极简的 Web 开发框架

3.5.1 Express简介

  1. 官网:http://www.expressjs.com.cn

  2. 安装:

  3. 作用:与 Node.js 内置的 http 模块类似,是专门用来创建 Web 服务器的

  4. 本质:就是一个 npm 上的第三方包,提供了快速创建 Web 服务器的便捷方法

  5. 服务器类型

    1)Web网站服务器:专门对外提供 Web 网页资源的服务器

    2)API 接口服务器:专门对外提供 API 接口的服务器

  6. 工具:配合Postman测试


3.5.2 Express基本用法

  1. 创建基本Web服务器

  2. 监听GET请求:app.get('URL',function(req,res){...})

    1)URL:客户端请求的URL地址

    2)req:请求对象(包含了与请求相关的属性与方法)

    3)res:响应对象(包含了与响应相关的属性与方法)

  3. 监听POST请求:app.post('URL',function(req,res){...})

    1)URL:客户端请求的URL地址

    2)req:请求对象(包含了与请求相关的属性与方法)

    3)res:响应对象(包含了与响应相关的属性与方法)

  4. 服务器把内容响应给客户端:res.send()

  5. 获取 URL 中携带的查询参数:req.query

    1)作用:可以访问到客户端通过查询字符串的形式,发送到服务器的参数

    2)注意:默认情况下,req.query 是一个空对象

    3)例:查询字符串为'?name=zs&age=20',则可访问 req.query.namereq.query.age

  6. 获取 URL 中的动态参数:req.params

    1)通过 ":参数名" 匹配动态参数,如:'/user/:id/:name'

    2)案例:输入 http://127.0.0.1/user/333/jason,此时 res.params={id:'333', name:'jason'}

    3)注意:默认情况下,req.params 是一个空对象

3.5.3 托管静态资源

  1. express.static():可非常方便地创建一个静态资源服务器,访问目录下的所有资源

    1)语法:app.use(express.static('指定的目录文件夹')

    2)注意:存放静态文件的目录名不会出现在 URL 中

  2. 托管多个静态资源目录:

    1)多次调用 express.static() 函数即可

    2)访问静态资源文件时,express.static() 函数会根据目录的添加顺序查找所需的文件

  3. 挂载路径前缀:

    1)如果希望根目录也出现在路径中,可以挂载路径前缀

    2)语法:app.use('/自定义路径', express.static('指定的目录文件夹')

3.5.4 路由Router

  1. 定义:客户端的请求与服务器处理函数之间的映射关系

  2. 构成:app.method(path, handler):请求的类型、请求的 URL 地址、处理函数,

  3. 匹配过程:

    1)每个请求按照定义的先后顺序进行匹配

    2)请求类型和请求的URL同时匹配成功,才会调用对应的处理函数

  4. 最简单的路由使用:直接把路由挂载到 app 上

  5. 模块化路由:

    1)创建路由模块对应的 .js 文件:router.js

    2)调用 express.Router() 函数创建路由对象:const router = express.Router()

    3)向路由对象上挂载具体的路由:router.get(...)router.post(...)

    4)使用 module.exports 向外共享路由对象:module.exports = router

    5)使用 app.use('/api', router) 函数注册全局中间件

3.5.5 中间件Middleware

3.5.5.1 中间件简介
  1. 定义:业务流程的中间处理环节
  2. 调用流程:当一个请求到达 Express 的服务器之后,可以连续调用多个中间件,从而对这次请求进行预处理
  3. 格式:app.use('/url',function(req, res, next) {...next()}
  4. 区别:中间件函数的形参列表中必须包含 next 参数,而路由处理函数中只包含 req 和 res
  5. next() 的作用:实现多个中间件连续调用的关键,表示把流转关系转交给下一个中间件或路由
  6. 注意:一定要在路由之前注册中间件;调用 next() 函数后不要再写额外的代码
3.5.5.2 中间件作用
  1. 多个中间件之间,共享同一份 req 和 res

  2. 可以在上游的中间件中,统一为 req 或 res 对象添加自定义的属性或方法,供下游的中间件或路由进行使用

3.5.5.3 全局与局部中间件
  1. 全局生效的中间件:客户端发起的任何请求,到达服务器之后都会触发的中间件

    1)语法:app.use(中间件函数)

    2)定义多个全局中间件:可用 app.use() 连续定义多个全局中间件,按照中间件定义的先后顺序依次进行调用

  2. 局部生效的中间件:不使用 app.use() 定义的中间件,仅在指定位置调用,其他请求不调用

    1)语法:app.get(url,中间件函数名,(req, res) =>{...}

    2)定义多个局部中间件:

    • 语法1:app.get(url, 中间件函数名1, 中间件函数名2, (req, res) =>{...}
    • 语法2:app.get(url, [中间件函数名1, 中间件函数名2], (req, res) =>{...}
3.5.5.4 中间件分类
  1. 应用级别的中间件:通过 app.use()app.get()app.post(),绑定到 app 实例上的中间件

  2. 路由级别的中间件:绑定到 express.Router() 实例上的中间件,与应用级别中间件无区别

  3. 错误级别的中间件:专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题,如throw new Error('服务器内部发生了错误!')

    1)处理函数的四个参数:err, req, res, next,其中 err.message,对应的就是Error中定义的消息

    2)注意:错误级别中间件必须注册在所有路由之后(其他的中间件都是注册在路由之前)

  4. Express 内置的中间件

    1)express.static:快速托管静态资源的内置中间件,例如: HTML 文件、图片、CSS 样式等(无兼容性)

    2)express.json:解析 JSON 格式的请求体数据(有兼容性:4.16.0+)

    • 测试:postman->【post请求】->body->raw->JSON
    • req.body:服务器通过此属性接收数据
    • 注意:如果不注册解析表单数据中间件,req.body=undefined

    3)express.urlencoded:解析 URL-encoded 格式的请求体数据(有兼容性:4.16.0+)

    • 写法:express.urlencoded({extended: false})
    • 测试:postman->【post请求】->body->x-www-form-urlencoded
  5. 第三方的中间件

    1)定义:非 Express 官方内置的,由第三方开发出来的中间件

    2)案例:body-parser,在express@4.16.0之前代替express.urlencoded的作用

  6. 自定义中间件:bodyParser

    1)直接定义中间件

    2)分模块写法


3.5.6 编写接口

3.5.6.1 编写路由
  1. 导入模块

  2. 编写接口

    1)GET接口:对应 req.query

    2)POST接口:对应 req.body

    3)DELETE接口

  3. 导出路由

3.5.6.2 编写服务器
  1. 导入模块

  2. 配置中间件

    1)配置urlencoded中间件

    2)配置JSONP接口

    3)配置cors中间件

  3. 导入路由并注册

  4. 启动服务器


3.6 跨域资源共享

作用:解决GET、POST接口的跨域请求

3.6.1 CORS

Cross-Origin Resource Sharing,由一系列 HTTP 响应头组成,决定浏览器是否阻止前端 JS 代码跨域获取资源

3.6.1.1 CORS基本使用
  1. 原理:接口服务器配置了 CORS 相关的 HTTP 响应头,就可以解除浏览器端的跨域访问限制

  2. 兼容性:IE10+、Chrome4+、FireFox3.5+

  3. 使用:主要在服务器端进行配置,客户端浏览器无须做任何额外的配置

3.6.1.2 Access-Control-Allow
  1. Origin:Access-Control-Allow-Origin:<origin> | *

    1)只允许来自指定地址的请求

    2)允许来自任何域的请求

  2. Headers

    1)默认情况下,CORS 仅支持客户端向服务器发送9类请求头

    • Accept
    • Accept-Language
    • Content-Language
    • DPR
    • Downlink
    • Save-Data
    • Viewport-Width
    • Width
    • Content-Type (text/plain、multipart/form-data、application/x-www-form-urlencoded )

    2)如果发送了额外的请求头信息,需要在服务器端通过 Access-Control-Allow-Headers 对额外的请求头进行声明

  3. Methods

    1)默认情况下,CORS 仅支持客户端发起 GET、POST、HEAD 请求

    2)想用PUT、DELETE 等方式请求服务器的资源,需要在服务器端通过 Access-Control-Alow-Methods指明实际请求所允许使用的 HTTP 方法

    3)例:只允许POST、GET、DELETE、HEAD方法

    4)例:允许所有的HTTP方法

3.6.1.3 请求分类
  1. 简单请求:客户端与服务器之间只会发生一次请求

    1)请求方式:GETPOSTHEAD

    2)请求头:9类请求头

  2. 预检请求:客户端与服务器之间会发生两次请求,OPTION 预检请求成功之后,才会发起真正的请求

    1)定义:在正式通信之前,浏览器会先发送 OPTION 请求进行预检,以获知服务器是否允许该实际请求。成功响应预检请求后,才会发送真正的请求并携带真实数据。

    2)满足以下任一条件:

    • 请求方式:除GETPOSTHEAD之外
    • 请求头:包含自定义头部字段
    • 向服务器发送了 application/json 格式的数据

3.6.2 JSONP

浏览器端通过 <script> 标签的 src 属性请求服务器上的数据,同时服务器返回一个函数的调用,仅支持GET请求。

  1. 特点:

    1)不属于真正的 Ajax 请求,因为没有使用 XMLHttpRequest 这个对象 2)仅支持 GET 请求,不支持 POST、PUT、DELETE 等请求

  2. 创建 JSONP 接口

    1)获取客户端发送过来的回调函数的名字

    2)得到要通过 JSONP 形式发送给客户端的数据

    3)根据前两步得到的数据,拼接出一个函数调用的字符串

    4)把上一步拼接得到的字符串,响应给客户端的 <script> 标签进行解析执行

    5)注意:如果项目中已经配置了 CORS 跨域资源共享,为了防止冲突必须在配置 CORS 中间件之前声明 JSONP 的接口

    6)完整代码

  3. 使用 jQuery 发起 JSONP 请求


3.7 MySQL

3.7.1 MySQL基本概念

  1. 分类:

    1)传统型数据库(关系型数据库/SQL 数据库)

    • MySQL(Community + Enterprise)
    • Oracle(收费)
    • SQL Server(收费)

    2)新型数据库(非关系型数据库/NoSQL 数据库)

    • MongoDB(Community + Enterprise)
  2. 传统型数据库的数据组织结构:数据库(database)、数据表(table)、数据行(row)、字段(field)

  3. 结构化查询语言SQL:Structured Query Language,是一门数据库编程语言,只能在关系型数据库中使用


3.7.2 MySQL基本用法

3.7.2.1 Workbench
  1. DataType 数据类型:

    1)int:整数

    2)varchar(20):字符串

    3)tinyint(1):布尔值

  2. 字段的特殊标识

    1)PK(Primary Key):主键、唯一标识

    2)NN(Not Null):值不允许为空

    3)UQ(Unique):值唯一

    4)AI(Auto Increment):值自动增长

3.7.2.2 SQL语句
  1. SELECT 语句:从表中查询数据 1)查询表格所有数据:SELECT * FROM 表名

    2)查询指定字段的数据:SELECT 列1,列2,... FROM table_name

    3)AS 关键字设置别名:SELECT 列1 AS 别名1, 列2 AS 别名2,... FROM 表名

  2. INSERT INTO 语句:向数据表中插入新的数据行

  3. UPDATE 语句:修改表中的数据

    1)UPDATE:指定要更新的表

    2)SET:指定要更新的列

    3)WHERE:指定更新的条件,如果不指定WHERE,会导致整张表被更新

  4. DELETE 语句:删除表中的行(如果不指定WHERE,会导致整张表被删除)

  5. WHERE 语句:限定选择的标准

    1)应用

    2)运算符

    • =、>、<、>=、<=
    • 不等于:<>、!=
    • BETWEEN:在某范围内
    • LIKE:搜索某种形式

    3)ANDOR 运算符:在 WHERE 子语句中把两个或多个条件结合起来

  6. ORDER BY 语句:根据指定的列对结果集进行排序

    1)升序:默认,ASC

    2)降序:DESC

    3)多重排序

3.7.2.3 SQL函数
  1. COUNT(*) 函数:返回查询结果的总数据条数


3.7.3 项目中操作MySQL

  1. 安装

  2. 连接

    1)配置 mysql 模块

    2)测试 mysql 模块

  3. 查询数据:SELECT 语句:results为数组

  4. 插入数据:INSERT INTO语句:results为对象

    1)传统方法:通过 affectedRows 属性,来判断是否插入数据成功

    2)便捷方法

  5. 更新数据:UPDATE语句:results为对象

    1)传统方法:通过 affectedRows 属性,来判断是否更新数据成功

    2)便捷方法:前提是数据对象的每个属性和数据表的字段一一对应

  6. 删除数据:DELETE语句:results为对象

  7. 标记删除:使用DELETE会真正删除数据,推荐用UPDATE将status改为1来模拟删除的状态


3.8 身份认证

3.8.1 Sessio认证机制

3.8.1.1 基于服务端渲染的传统模式
  1. 定义:服务器发送给客户端的 HTML 页面,是在服务器通过字符串的拼接动态生成的,客户端无需使用Ajax请求页面数据

    1)优点:

    • 前端耗时少:服务器端负责动态生成 HTML 内容,浏览器只需要直接渲染页面即可
    • 有利于SEO:服务器端响应的是完整的 HTML 页面,爬虫更容易爬取获得信息

    2)缺点:

    • 占用服务器端资源:服务器端完成 HTML 页面内容的拼接,如果请求较多会对服务器造成一定的访问压力
    • 不利于前后端分离:无法进行分工合作,尤其对于前端复杂度高的项目,开发效率低
  2. HTTP 协议的无状态性

    1)定义:客户端的每次 HTTP 请求都是独立的,连续多个请求之间没有直接的关系,服务器不会主动保留每次 HTTP 请求的状态

    2)突破限制方法:Cookie

  3. Cookie:存储在用户浏览器中的一段不超过 4 KB 的字符串

    1)结构:由一个名称(Name)、一个值(Value)和其它几个用于控制 Cookie 有效期、安全性、使用范围的可选属性组成

    2)发送:不同域名下的 Cookie 各自独立,每当客户端发起请求时,会自动把当前域名下所有未过期的 Cookie 一同发送到服务器

    3)特性:自动发送、域名独立、过期时限、4KB 限制

    4)流程:

    • 客户端第一次请求服务器时,服务器通过响应头的形式,向客户端发送一个身份认证的 Cookie,客户端会自动将 Cookie 保存在浏览器中
    • 随后当客户端浏览器每次请求服务器时,浏览器会自动将身份认证相关的 Cookie,通过请求头的形式发送给服务器,服务器即可验明客户端的身份

    5)不安全:Cookie 是存储在浏览器中的,且浏览器也提供了读写 Cookie 的 API,因此 Cookie 很容易被伪造

3.8.1.2 Session认证

session认证机制

  1. 适用场景:当前端请求后端接口【不存在跨域问题】的时候,推荐使用 Session 身份认证机制

  2. 局限性:需要配合 Cookie 才能实现,由于 Cookie 默认不支持跨域访问,所以当涉及到前端跨域请求后端接口时,需要做很多额外的配置

  3. 安装:

  4. 使用步骤:

  5. 登录案例:

    1)后端接口:app.js

    2)前端页面:pages/


3.8.2 JWT认证机制

JSON Web Token,是目前最流行的跨域认证解决方案。

3.8.2.1 基于前后端分离的新型模式
  1. 定义:后端只负责提供 API 接口,前端使用 Ajax 调用接口

  2. 优点:

    1)开发体验好:前端专注于 UI 页面的开发,后端专注于API 的开发

    2)用户体验好:Ajax 技术可以轻松实现页面的局部刷新

    3)减轻服务器端压力:页面最终是在每个用户的浏览器中生成的

  3. 缺点:

    1)不利于 SEO:完整的 HTML 页面需要在客户端动态拼接完成,爬虫对无法爬取页面的有效信息

    2)解决方案:利用 Vue、React 等前端框架的 SSR (server side render)技术

3.8.2.2 JWT认证

JWT认证机制

  1. 适用场景:当前端需要跨域请求后端接口的时候,推荐使用 JWT 认证机制

  2. 流程:用户的信息通过 Token 字符串的形式,保存在客户端浏览器中;服务器通过还原 Token 字符串的形式来认证用户的身份

  3. 结构:三部分组成,分别是 Header(头部)、Payload(有效荷载)、Signature(签名),三者之间用“.”分隔

    1)Payload(有效荷载):真正的用户信息,它是用户信息经过加密之后生成的字符串

    2)Header(头部)、Signature(签名):安全性相关的部分,只是为了保证 Token 的安全性

  4. 使用方式:

    1)语法:Authorzation: Bearer <token>

    2)客户端收到服务器返回的 JWT 之后,通常会将它储存在 localStorage 或 sessionStorage 中

    3)此后客户端每次与服务器通信,都要带上这个 JWT 的字符串进行身份认证,把 JWT 放在 HTTP 请求头的 Authorization 字段中

  5. 安装:

  6. 使用步骤

    1)导入:jsonwebtokenexpress-jwt/libcorsbody-parser

    2)定义 secret 密钥:const secretKey = 'XXXXXXXX'

    • 加密:生成 JWT 字符串时,使用 secret 密钥对用户的信息进行加密,最终得到加密好的 JWT 字符串
    • 解密:把 JWT 字符串解析还原成 JSON 对象的时候,使用 secret 密钥进行解密

    3)登录成功后生成 JWT 字符串:jwt.sign({ username: userinfo.username },secretKey, {expiresIn:'30s'})

    • 注意:千万不要把密码加密到 token 字符中

    4)注册 express-jwt 中间件:app.use(expressJWT({ secret: secretKey }).unless({ path: [/^\/api\//] }))

    • 原理:客户端每次在访问那些有权限接口时,都需要主动通过请求头中的 Authorization 字段,将 Token 字符串发送到服务器进行身份认证,服务器可以通过 express-jwt自动将客户端发送过来的 Token 解析还原成 JSON 对象
    • 作用:可以把解析出来的用户信息,挂载到 req.user 属性上
    • 可用 unless 指定哪些接口不需要访问权限

    5)使用 req.user 获取用户信息

    • 作用:express-jwt配置成功后,可在那些有权限的接口中使用 req.user 对象访问从 JWT 字符串中解析出来的用户信息
    • Postman测试:GET->Headers->Authorization: Bearer <token>(注意token的有效时长)
    • 返回示例:{ username: 'admin', iat: 1641140151, exp: 1641140181 }

    6)捕获解析 JWT 失败后产生的错误:app.use((err, req, res, next) => {...})

    • 若客户端发送过来的 Token 字符串过期或不合法,会产生解析失败的错误,可通过 Express 的错误中间件捕获错误并处理
    • token 解析失败错误:err.name == 'UnauthorizedError'